fixed compile problem
[swftools.git] / lib / python / gfx.c
1 /* gfx.c
2
3    Python wrapper for gfx convert
4
5    Part of the swftools package.
6
7    Copyright (c) 2003 Matthias Kramm <kramm@quiss.org>
8  
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
22
23 #include <Python.h>
24 #undef HAVE_STAT
25 #include "../devices/swf.h"
26 #include "../devices/render.h"
27 #include "../devices/rescale.h"
28 #include "../devices/text.h"
29 #include "../pdf/pdf.h"
30 #include "../log.h"
31 #include "../utf8.h"
32
33 gfxsource_t*pdfdriver;
34
35 staticforward PyTypeObject OutputClass;
36 staticforward PyTypeObject PageClass;
37 staticforward PyTypeObject DriverClass;
38
39 typedef struct {
40     PyObject_HEAD
41     gfxdevice_t*output_device;
42 } OutputObject;
43
44 typedef struct {
45     PyObject_HEAD
46     PyObject*parent;
47     gfxpage_t*page;
48     int nr;
49 } PageObject;
50
51 typedef struct {
52     PyObject_HEAD
53     gfxdocument_t*doc;
54     char*filename;
55 } DocObject;
56
57 static char* strf(char*format, ...)
58 {
59     char buf[1024];
60     int l;
61     va_list arglist;
62     va_start(arglist, format);
63     vsprintf(buf, format, arglist);
64     va_end(arglist);
65     return strdup(buf);
66 }
67 #define PY_ERROR(s,args...) (PyErr_SetString(PyExc_Exception, strf(s, ## args)),NULL)
68 #define PY_NONE Py_BuildValue("s", 0)
69
70 //---------------------------------------------------------------------
71 staticforward PyObject* output_save(PyObject* _self, PyObject* args, PyObject* kwargs);
72 staticforward PyObject* output_startpage(PyObject* _self, PyObject* args, PyObject* kwargs);
73 staticforward PyObject* output_endpage(PyObject* _self, PyObject* args, PyObject* kwargs);
74
75 static PyMethodDef output_methods[] =
76 {
77     /* Output functions */
78     {"save", (PyCFunction)output_save, METH_KEYWORDS, ""},
79     {"startpage", (PyCFunction)output_startpage, METH_KEYWORDS, ""},
80     {"endpage", (PyCFunction)output_endpage, METH_KEYWORDS, ""},
81     {0,0,0,0}
82 };
83 static PyObject* output_save(PyObject* _self, PyObject* args, PyObject* kwargs)
84 {
85     OutputObject* self = (OutputObject*)_self;
86     char*filename = 0;
87     static char *kwlist[] = {"filename", NULL};
88     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &filename))
89         return NULL;
90
91     gfxresult_t*result = self->output_device->finish(self->output_device);
92     self->output_device = 0;
93     if(result->save(result, filename) < 0) {
94         return PY_ERROR("Couldn't write to %s", filename);
95     }
96     result->destroy(result);
97     return PY_NONE;
98 }
99 static PyObject* output_startpage(PyObject* _self, PyObject* args, PyObject* kwargs)
100 {
101     OutputObject* self = (OutputObject*)_self;
102     int width=0, height=0;
103     if (!PyArg_ParseTuple(args, "ii", &width, &height))
104         return NULL;
105     self->output_device->startpage(self->output_device, width, height);
106     return PY_NONE;
107 }
108 static PyObject* output_endpage(PyObject* _self, PyObject* args, PyObject* kwargs)
109 {
110     OutputObject* self = (OutputObject*)_self;
111     if (!PyArg_ParseTuple(args, ""))
112         return NULL;
113     self->output_device->endpage(self->output_device);
114     return PY_NONE;
115 }
116 static PyObject* f_createSWF(PyObject* parent, PyObject* args, PyObject* kwargs)
117 {
118     static char *kwlist[] = {NULL};
119     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist))
120         return NULL;
121     OutputObject*self = PyObject_New(OutputObject, &OutputClass);
122     
123     self->output_device = malloc(sizeof(gfxdevice_t));
124     gfxdevice_swf_init(self->output_device);
125     return (PyObject*)self;
126 }
127 static PyObject* f_createImageList(PyObject* parent, PyObject* args, PyObject* kwargs)
128 {
129     static char *kwlist[] = {NULL};
130     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist))
131         return NULL;
132     OutputObject*self = PyObject_New(OutputObject, &OutputClass);
133     
134     self->output_device = malloc(sizeof(gfxdevice_t));
135     gfxdevice_render_init(self->output_device);
136     return (PyObject*)self;
137 }
138 static PyObject* f_createPlainText(PyObject* parent, PyObject* args, PyObject* kwargs)
139 {
140     static char *kwlist[] = {NULL};
141     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist))
142         return NULL;
143     OutputObject*self = PyObject_New(OutputObject, &OutputClass);
144     
145     self->output_device = malloc(sizeof(gfxdevice_t));
146     gfxdevice_text_init(self->output_device);
147     return (PyObject*)self;
148 }
149
150
151 static void output_dealloc(PyObject* _self) {
152     OutputObject* self = (OutputObject*)_self;
153
154     if(self->output_device) {
155         gfxresult_t*result = self->output_device->finish(self->output_device);
156         result->destroy(result);result=0;
157         self->output_device = 0;
158     }
159     
160     PyObject_Del(self);
161 }
162 static PyObject* output_getattr(PyObject * _self, char* a)
163 {
164     OutputObject*self = (OutputObject*)_self;
165     
166 /*    if(!strcmp(a, "x1")) {
167         return PyInt_FromLong(self->output_device->x1);
168     } else if(!strcmp(a, "y1")) {
169         return PyInt_FromLong(self->output_device->y1);
170     } else if(!strcmp(a, "x2")) {
171         return PyInt_FromLong(self->output_device->x2);
172     } else if(!strcmp(a, "y2")) {
173         return PyInt_FromLong(self->output_device->y2);
174     }*/
175     
176     return Py_FindMethod(output_methods, _self, a);
177 }
178 static int output_setattr(PyObject * _self, char* a, PyObject * o) 
179 {
180     OutputObject*self = (OutputObject*)_self;
181     if(!PyString_Check(o))
182         return -1;
183     char*value = PyString_AsString(o);
184     self->output_device->setparameter(self->output_device, a, value);
185     return -1;
186 }
187 static int output_print(PyObject * _self, FILE *fi, int flags)
188 {
189     OutputObject*self = (OutputObject*)_self;
190     fprintf(fi, "%08x(%d)", (int)_self, _self?_self->ob_refcnt:0);
191     return 0;
192 }
193
194 //---------------------------------------------------------------------
195 staticforward PyObject* page_render(PyObject* _self, PyObject* args, PyObject* kwargs);
196 staticforward PyObject* page_asImage(PyObject* _self, PyObject* args, PyObject* kwargs);
197
198 static PyMethodDef page_methods[] =
199 {
200     /* Page functions */
201     {"render", (PyCFunction)page_render, METH_KEYWORDS, ""},
202     {"asImage", (PyCFunction)page_asImage, METH_KEYWORDS, ""},
203     {0,0,0,0}
204 };
205 static PyObject* page_render(PyObject* _self, PyObject* args, PyObject* kwargs)
206 {
207     PageObject* self = (PageObject*)_self; 
208     
209     static char *kwlist[] = {"dev", "move", "clip", NULL};
210     OutputObject*output = 0;
211     PyObject*move=0;
212     PyObject*clip=0;
213     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|OO", kwlist, &OutputClass, &output,
214                 &move,&clip
215                 ))
216         return NULL;
217
218     int x=0,y=0;
219     int cx1=0,cy1=0,cx2=0,cy2=0;
220
221     if(move) {
222         if (!PyArg_ParseTuple(move, "ii", &x,&y))
223             return NULL;
224     }
225     if(clip) {
226         if (!PyArg_ParseTuple(clip, "iiii", &cx1,&cy1,&cx2,&cy2))
227             return NULL;
228     }
229
230     if(x|y|cx1|cx2|cy1|cy2)
231         self->page->rendersection(self->page, output->output_device,x,y,cx1,cy1,cx2,cy2);
232     else
233         self->page->render(self->page, output->output_device);
234     return PY_NONE;
235 }
236
237 static PyObject* page_asImage(PyObject* _self, PyObject* args, PyObject* kwargs)
238 {
239     PageObject* self = (PageObject*)_self; 
240     
241     static char *kwlist[] = {"width", "height", NULL};
242     int width=0,height=0;
243     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii", kwlist, &width, &height))
244         return NULL;
245
246     if(!width || !height) {
247         return PY_ERROR("invalid dimensions: %dx%d", width,height);
248     }
249
250     gfxdevice_t dev1,dev2;
251     gfxdevice_render_init(&dev1);
252     dev1.setparameter(&dev1, "antialise", "2");
253     gfxdevice_rescale_init(&dev2, &dev1, width, height);
254     dev2.startpage(&dev2, self->page->width, self->page->height);
255     self->page->render(self->page, &dev2);
256     dev2.endpage(&dev2);
257     gfxresult_t*result = dev2.finish(&dev2);
258     gfximage_t*img = (gfximage_t*)result->get(result,"page0");
259     int l = img->width*img->height;
260     unsigned char*data = malloc(img->width*img->height*3);
261     int s,t;
262     for(t=0,s=0;t<l;s+=3,t++) {
263         data[s+0] = img->data[t].r;
264         data[s+1] = img->data[t].g;
265         data[s+2] = img->data[t].b;
266     }
267     result->destroy(result);
268     return PyString_FromStringAndSize((char*)data,img->width*img->height*3);
269 }
270
271 static void page_dealloc(PyObject* _self) {
272     PageObject* self = (PageObject*)_self; 
273     if(self->page) {
274         self->page->destroy(self->page);
275         self->page=0;
276     }
277     if(self->parent) {
278         Py_DECREF(self->parent);
279         self->parent=0;
280     }
281     
282     PyObject_Del(self);
283 }
284 static PyObject* page_getattr(PyObject * _self, char* a)
285 {
286     PageObject*self = (PageObject*)_self;
287     
288     if(!strcmp(a, "size")) {
289         return Py_BuildValue("(ii)", self->page->width, self->page->height);
290     } if(!strcmp(a, "doc")) {
291         Py_INCREF(self->parent);
292         return self->parent;
293     } if(!strcmp(a, "nr")) {
294         return PyInt_FromLong(self->nr);
295     } else if(!strcmp(a, "width")) {
296         return PyInt_FromLong(self->page->width);
297     } else if(!strcmp(a, "height")) {
298         return PyInt_FromLong(self->page->height);
299     }
300     return Py_FindMethod(page_methods, _self, a);
301 }
302 static int page_setattr(PyObject * self, char* a, PyObject * o) {
303     return -1;
304 }
305 static int page_print(PyObject * _self, FILE *fi, int flags)
306 {
307     PageObject*self = (PageObject*)_self;
308     fprintf(fi, "%08x(%d)", (int)_self, _self?_self->ob_refcnt:0);
309     return 0;
310 }
311
312 //---------------------------------------------------------------------
313
314 staticforward PyObject* doc_getPage(PyObject* parent, PyObject* args, PyObject* kwargs);
315 staticforward PyObject* doc_getInfo(PyObject* parent, PyObject* args, PyObject* kwargs);
316 staticforward PyObject* doc_setParameter(PyObject* parent, PyObject* args, PyObject* kwargs);
317
318 static PyMethodDef doc_methods[] =
319 {
320     /* PDF functions */
321     {"getPage", (PyCFunction)doc_getPage, METH_KEYWORDS, ""},
322     {"getInfo", (PyCFunction)doc_getInfo, METH_KEYWORDS, ""},
323     {"setParameter", (PyCFunction)doc_setParameter, METH_KEYWORDS, ""},
324     {0,0,0,0}
325 };
326
327 static PyObject* doc_getPage(PyObject* _self, PyObject* args, PyObject* kwargs)
328 {
329     DocObject* self = (DocObject*)_self;
330
331     static char *kwlist[] = {"nr", NULL};
332     int pagenr = 0;
333     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &pagenr))
334         return NULL;
335
336     PageObject*page = PyObject_New(PageObject, &PageClass);
337     page->page = self->doc->getpage(self->doc, pagenr);
338     page->nr = pagenr;
339     page->parent = _self;
340     Py_INCREF(page->parent);
341     if(!page->page) {
342         PyObject_Del(page);
343         return PY_ERROR("Couldn't extract page %d", pagenr);
344     }
345     return (PyObject*)page;
346 }
347
348 static PyObject* doc_getInfo(PyObject* _self, PyObject* args, PyObject* kwargs)
349 {
350     DocObject* self = (DocObject*)_self;
351
352     static char *kwlist[] = {"key", NULL};
353     char*key = 0;
354     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &key))
355         return NULL;
356
357     char*s = self->doc->getinfo(self->doc, key);
358     return PyString_FromString(s);
359 }
360
361 static PyObject* doc_setParameter(PyObject* _self, PyObject* args, PyObject* kwargs)
362 {
363     DocObject* self = (DocObject*)_self;
364
365     static char *kwlist[] = {"key", "value", NULL};
366     char*key = 0, *value=0;
367     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &key,&value))
368         return NULL;
369
370     self->doc->set_parameter(self->doc, key, value);
371     return PY_NONE;
372 }
373
374 static PyObject* f_open(PyObject* parent, PyObject* args, PyObject* kwargs)
375 {
376     static char *kwlist[] = {"type", "filename", NULL};
377     char*filename;
378     char*type;
379     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &type, &filename))
380         return NULL;
381
382     DocObject*self = PyObject_New(DocObject, &DriverClass);
383    
384     if(!strcmp(type,"pdf"))
385         self->doc = pdfdriver->open(filename);
386     else
387         return PY_ERROR("Unknown type %s", type);
388
389     if(!self->doc) {
390         PyObject_Del(self);
391         return PY_ERROR("Couldn't open %s", filename);
392     }
393     self->filename = strdup(filename);
394     return (PyObject*)self;
395 }
396 static void doc_dealloc(PyObject* _self) {
397     DocObject* self = (DocObject*)_self;
398     if(self->doc) {
399         self->doc->destroy(self->doc);
400         self->doc=0;
401     }
402     if(self->filename) {
403         free(self->filename);self->filename=0;
404     }
405     PyObject_Del(self);
406 }
407 static PyObject* doc_getattr(PyObject * _self, char* a)
408 {
409     DocObject*self = (DocObject*)_self;
410     if(!strcmp(a, "pages")) {
411         return PyInt_FromLong(self->doc->num_pages);
412     }
413     if(!strcmp(a, "filename")) {
414         return PyString_FromString(self->filename);
415     }
416     return Py_FindMethod(doc_methods, _self, a);
417 }
418 static int doc_setattr(PyObject * self, char* a, PyObject * o) {
419     return -1;
420 }
421 static int doc_print(PyObject * _self, FILE *fi, int flags)
422 {
423     DocObject*self = (DocObject*)_self;
424     fprintf(fi, "%08x(%d)", (int)_self, _self?_self->ob_refcnt:0);
425     return 0;
426 }
427
428 //---------------------------------------------------------------------
429
430 static PyTypeObject OutputClass =
431 {
432     PyObject_HEAD_INIT(NULL)
433     0,
434     tp_name: "Output",
435     tp_basicsize: sizeof(OutputObject),
436     tp_itemsize: 0,
437     tp_dealloc: output_dealloc,
438     tp_print: output_print,
439     tp_getattr: output_getattr,
440     tp_setattr: output_setattr,
441 };
442 static PyTypeObject PageClass =
443 {
444     PyObject_HEAD_INIT(NULL)
445     0,
446     tp_name: "Page",
447     tp_basicsize: sizeof(PageObject),
448     tp_itemsize: 0,
449     tp_dealloc: page_dealloc,
450     tp_print: page_print,
451     tp_getattr: page_getattr,
452     tp_setattr: page_setattr,
453 };
454 static PyTypeObject DriverClass =
455 {
456     PyObject_HEAD_INIT(NULL)
457     0,
458     tp_name: "PDF",
459     tp_basicsize: sizeof(DocObject),
460     tp_itemsize: 0,
461     tp_dealloc: doc_dealloc,
462     tp_print: doc_print,
463     tp_getattr: doc_getattr,
464     tp_setattr: doc_setattr,
465 };
466
467 //=====================================================================
468
469 static PyObject* f_setoption(PyObject* self, PyObject* args, PyObject* kwargs)
470 {
471     static char *kwlist[] = {"key", "value", NULL};
472     char*key=0,*value=0;
473     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss", kwlist, &key, &value))
474         return NULL;
475     pdfdriver->set_parameter(pdfdriver,key,value);
476     return PY_NONE;
477 }
478
479 static PyObject* f_verbose(PyObject* self, PyObject* args, PyObject* kwargs)
480 {
481     static char *kwlist[] = {"val", NULL};
482     int val;
483     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &val))
484         return NULL;
485     setConsoleLogging(val);
486     return PY_NONE;
487 }
488
489 static PyObject* f_addfont(PyObject* self, PyObject* args, PyObject* kwargs)
490 {
491     static char *kwlist[] = {"filename", NULL};
492     char*filename=0;
493     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &filename))
494         return NULL;
495     pdfdriver->set_parameter(pdfdriver,"font", filename);
496     return PY_NONE;
497 }
498
499 static PyObject* f_addfontdir(PyObject* self, PyObject* args, PyObject* kwargs)
500 {
501     static char *kwlist[] = {"filename", NULL};
502     char*filename=0;
503     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &filename))
504         return NULL;
505     pdfdriver->set_parameter(pdfdriver,"fontdir", filename);
506     return PY_NONE;
507 }
508
509 static PyMethodDef pdf2swf_methods[] =
510 {
511     /* sources */
512     {"open", (PyCFunction)f_open, METH_KEYWORDS, ""},
513     {"addfont", (PyCFunction)f_addfont, METH_KEYWORDS, ""},
514     {"addfontdir", (PyCFunction)f_addfontdir, METH_KEYWORDS, ""},
515     {"setoption", (PyCFunction)f_setoption, METH_KEYWORDS, ""},
516     {"verbose", (PyCFunction)f_verbose, METH_KEYWORDS, ""},
517
518     /* devices */
519     {"SWF", (PyCFunction)f_createSWF, METH_KEYWORDS, ""},
520     {"ImageList", (PyCFunction)f_createImageList, METH_KEYWORDS, ""},
521     {"PlainText", (PyCFunction)f_createPlainText, METH_KEYWORDS, ""},
522
523     /* sentinel */
524     {0, 0, 0, 0}
525 };
526
527 void initgfx(void)
528 {
529     initLog(0,0,0,0,0,2);
530     OutputClass.ob_type = &PyType_Type;
531     PageClass.ob_type = &PyType_Type;
532     DriverClass.ob_type = &PyType_Type;
533  
534     pdfdriver = gfxsource_pdf_create();
535     
536     PyObject*module = Py_InitModule("gfx", pdf2swf_methods);
537 }