added bbox attribute to text tag.
[swftools.git] / lib / python / primitives.c
1 /* primitives.c
2
3    Python wrapper for librfxswf- primitive objects (implementation)
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 "../rfxswf.h"
26 #include "../log.h"
27 #include "./pyutils.h"
28 #include "primitives.h"
29
30 //----------------------------------------------------------------------------
31 typedef struct {
32     PyObject_HEAD
33     RGBA rgba;
34 } ColorObject;
35
36 PyObject* f_Color(PyObject* self, PyObject* args, PyObject* kwargs)
37 {
38     static char *kwlist[] = {"r", "g", "b", "a", NULL};
39     ColorObject* color;
40     int r=0,g=0,b=0,a=255;
41     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii|i", kwlist, &r,&g,&b,&a))
42         return NULL;
43     color = PyObject_New(ColorObject, &ColorClass);
44     mylog("+%08x(%d) color_new(%d,%d,%d,%d)\n", (int)color, color->ob_refcnt, r,g,b,a);
45     color->rgba.r = r;
46     color->rgba.g = g;
47     color->rgba.b = b;
48     color->rgba.a = a;
49     return (PyObject*)color;
50 }
51 static PyObject* color_getattr(PyObject * self, char* a)
52 {
53     ColorObject*color = (ColorObject*)self;
54     if(!strcmp(a, "r")) {
55         return Py_BuildValue("r", color->rgba.r);
56     } else if(!strcmp(a, "g")) {
57         return Py_BuildValue("g", color->rgba.g);
58     } else if(!strcmp(a, "b")) {
59         return Py_BuildValue("b", color->rgba.b);
60     } else if(!strcmp(a, "a")) {
61         return Py_BuildValue("a", color->rgba.a);
62     }
63     return NULL;
64 }
65 static int color_setattr(PyObject * self, char* attr, PyObject* o)
66 {
67     ColorObject*color = (ColorObject*)self;
68     if(!strcmp(attr, "r")) {
69         if (!PyArg_Parse(o, "d", &color->rgba.r)) goto err;
70         return 0;
71     } else if(!strcmp(attr, "g")) {
72         if (!PyArg_Parse(o, "d", &color->rgba.g)) goto err;
73         return 0;
74     } else if(!strcmp(attr, "b")) {
75         if (!PyArg_Parse(o, "d", &color->rgba.b)) goto err;
76         return 0;
77     } else if(!strcmp(attr, "a")) {
78         if (!PyArg_Parse(o, "d", &color->rgba.a)) goto err;
79         return 0;
80     } 
81 err:
82     mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, attr, o);
83     return 1;
84 }
85 RGBA color_getRGBA(PyObject*self)
86 {
87     ColorObject*color = 0;
88     if (!PyArg_Parse(self, "O!", &ColorClass, &color)) {
89         RGBA dummy;
90         memset(&dummy, 0, sizeof(dummy));
91         mylog("Error: wrong type for function color_getRGBA");
92         return dummy;
93     }
94     return color->rgba;
95 }
96 void color_dealloc(PyObject* self)
97 {
98     mylog("-%08x(%d) color_dealloc\n", (int)self, self->ob_refcnt);
99     PyObject_Del(self);
100 }
101 PyTypeObject ColorClass = 
102 {
103     PyObject_HEAD_INIT(NULL)
104     0,
105     tp_name: "Color",
106     tp_basicsize: sizeof(ColorObject),
107     tp_itemsize: 0,
108     tp_dealloc: color_dealloc,
109     tp_print: 0,
110     tp_getattr: color_getattr,
111     tp_setattr: color_setattr,
112 };
113 //----------------------------------------------------------------------------
114 typedef struct {
115     PyObject_HEAD
116     SRECT bbox;
117 } BBoxObject;
118 //void swf_ExpandRect(SRECT*src, SPOINT add);
119 //void swf_ExpandRect2(SRECT*src, SRECT*add);
120
121 PyObject* f_BBox(PyObject* self, PyObject* args, PyObject* kwargs)
122 {
123     static char *kwlist[] = {"xmin", "ymin", "xmax", "ymax", NULL};
124     BBoxObject* bbox;
125     float xmin,ymin,xmax,ymax;
126     if(!kwargs) {
127         if (!PyArg_ParseTuple(args, "ffff", &xmin, &ymin, &xmax, &ymax))
128             return NULL;
129     } else {
130         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ffff", kwlist, &xmin, &ymin, &xmax, &ymax))
131             return NULL;
132     }
133     SRECT box;
134     box.xmin = (int)(xmin*20);
135     box.ymin = (int)(ymin*20);
136     box.xmax = (int)(xmax*20);
137     box.ymax = (int)(ymax*20);
138     mylog("+%08x(%d) bbox_new(%d,%d,%d,%d)\n", (int)self, self?self->ob_refcnt:0, box.xmin, box.ymin, box.xmax,box.ymax);
139     bbox = PyObject_New(BBoxObject, &BBoxClass);
140     bbox->bbox = box;
141     return (PyObject*)bbox;
142 }
143 static PyObject* bbox_getattr(PyObject * self, char* a)
144 {
145     BBoxObject*bbox = (BBoxObject*)self;
146     if(!strcmp(a, "xmin")) {
147         return Py_BuildValue("f", bbox->bbox.xmin/20.0);
148     } else if(!strcmp(a, "ymin")) {
149         return Py_BuildValue("f", bbox->bbox.ymin/20.0);
150     } else if(!strcmp(a, "xmax")) {
151         return Py_BuildValue("f", bbox->bbox.xmax/20.0);
152     } else if(!strcmp(a, "ymax")) {
153         return Py_BuildValue("f", bbox->bbox.ymax/20.0);
154     }
155     return NULL;
156 }
157 static int bbox_setattr(PyObject * self, char* a, PyObject* o)
158 {
159     BBoxObject*bbox= (BBoxObject*)self;
160     if(!strcmp(a, "xmin")) {
161         float xmin;
162         if (!PyArg_Parse(o, "i", &xmin)) goto err;
163         bbox->bbox.xmin = (int)(xmin*20);
164         return 0;
165     } else if(!strcmp(a, "ymin")) {
166         float ymin;
167         if (!PyArg_Parse(o, "i", &ymin)) goto err;
168         bbox->bbox.ymin = (int)(ymin*20);
169         return 0;
170     } else if(!strcmp(a, "xmax")) {
171         float xmax;
172         if (!PyArg_Parse(o, "i", &xmax)) goto err;
173         bbox->bbox.xmax = (int)(xmax*20);
174         return 0;
175     } else if(!strcmp(a, "ymax")) {
176         float ymax;
177         if (!PyArg_Parse(o, "i", &ymax)) goto err;
178         bbox->bbox.ymax = (int)(ymax*20);
179         return 0;
180     } 
181 err:
182     mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
183     return 1;
184 }
185 void bbox_dealloc(PyObject* self)
186 {
187     mylog("-%08x(%d) bbox_dealloc\n", (int)self, self->ob_refcnt);
188     PyObject_Del(self);
189 }
190 SRECT bbox_getSRECT(PyObject*self)
191 {
192     BBoxObject*bbox= 0;
193     if (!PyArg_Parse(self, "O!", &BBoxClass, &bbox)) {
194         SRECT dummy;
195         memset(&dummy, 0, sizeof(dummy));
196         mylog("Error: wrong type for function color_getRGBA");
197         return dummy;
198     }
199     return bbox->bbox;
200 }
201 PyTypeObject BBoxClass = 
202 {
203     PyObject_HEAD_INIT(NULL)
204     0,
205     tp_name: "BBox",
206     tp_basicsize: sizeof(BBoxObject),
207     tp_itemsize: 0,
208     tp_dealloc: bbox_dealloc,
209     tp_print: 0,
210     tp_getattr: bbox_getattr,
211     tp_setattr: bbox_setattr,
212 };
213 SRECT bbox_getBBox(PyObject*self);
214 //----------------------------------------------------------------------------
215 typedef struct {
216     PyObject_HEAD
217     MATRIX matrix;
218 } MatrixObject;
219
220 PyObject* f_Matrix(PyObject* _self, PyObject* args, PyObject* kwargs)
221 {
222     PyObject*self = (PyObject*)PyObject_New(MatrixObject, &MatrixClass);
223     MatrixObject*matrix = (MatrixObject*)self;
224     mylog("+%08x(%d) f_Matrix", self, self->ob_refcnt);
225     static char *kwlist[] = {"x", "y", "scale", "rotate", "pivotx", "pivoty", NULL};
226     float x=0,y=0,scale=1.0,rotate=0,pivotx,pivoty;
227     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ffffff", kwlist, &x,&y,&scale,&rotate,&pivotx,&pivoty))
228         return NULL;
229     mylog(" %08x(%d) f_Matrix: x=%f y=%f scale=%f rotate=%f", self, self->ob_refcnt, x,y,scale,rotate);
230     swf_GetMatrix(0, &matrix->matrix);
231
232     matrix->matrix.tx = (int)(x*20);
233     matrix->matrix.ty = (int)(y*20);
234
235     if(!rotate) {
236         matrix->matrix.sx = (int)(scale*65536);
237         matrix->matrix.sy = (int)(scale*65536);
238     } else {
239         matrix->matrix.sx = (int)(scale*cos(rotate)*65536);
240         matrix->matrix.sy = (int)(scale*cos(rotate)*65536);
241         matrix->matrix.r0 = (int)(scale*sin(rotate)*65536);
242         matrix->matrix.r1 = (int)(-scale*sin(rotate)*65536);
243     }
244     if(pivotx || pivoty) {
245         SPOINT p,d;
246         p.x = (int)(pivotx*20);
247         p.y = (int)(pivoty*20);
248         p = swf_TurnPoint(p, &matrix->matrix);
249         matrix->matrix.tx += matrix->matrix.tx-p.x;
250         matrix->matrix.ty += matrix->matrix.ty-p.y;
251     }
252
253     /* TODO: rotate */
254     return self;
255 }
256 static PyObject* matrix_getattr(PyObject * self, char* a)
257 {
258     PY_ASSERT_TYPE(self,&MatrixClass);
259     return NULL;
260 }
261 static int matrix_setattr(PyObject * self, char* a, PyObject* o)
262 {
263     PY_ASSERT_TYPE(self,&MatrixClass);
264     return 0;
265 }
266 MATRIX matrix_getMatrix(PyObject*self)
267 {
268     mylog(" %08x(%d) matrix_getMatrix", self, self->ob_refcnt);
269     PY_ASSERT_TYPE(self,&MatrixClass);
270     MatrixObject*matrix = (MatrixObject*)self;
271     return matrix->matrix;
272 }
273 void matrix_dealloc(PyObject* self)
274 {
275     mylog("-%08x(%d) matrix_dealloc", self, self->ob_refcnt);
276     PyObject_Del(self);
277 }
278 //SPOINT swf_TurnPoint(SPOINT p, MATRIX* m);
279 //SRECT swf_TurnRect(SRECT r, MATRIX* m);
280 PyTypeObject MatrixClass = 
281 {
282     PyObject_HEAD_INIT(NULL)
283     0,
284     tp_name: "Matrix",
285     tp_basicsize: sizeof(MatrixObject),
286     tp_itemsize: 0,
287     tp_dealloc: matrix_dealloc,
288     tp_print: 0,
289     tp_getattr: matrix_getattr,
290     tp_setattr: matrix_setattr,
291     tp_compare: 0,
292     tp_repr: 0,
293     tp_as_number: 0,
294     tp_as_sequence: 0,
295     tp_as_mapping: 0,
296     tp_hash: 0,     // dict(x)
297     tp_call: 0,     // x()
298     tp_str: 0       // str(x)
299 };
300 //----------------------------------------------------------------------------
301 typedef struct {
302     PyObject_HEAD
303     CXFORM cxform;
304 } CXFormObject;
305
306 PyObject* f_ColorTransform(PyObject* self, PyObject* args, PyObject* kwargs)
307 {
308     return NULL;
309 }
310 static PyObject* colortransform_getattr(PyObject * self, char* a)
311 {
312     return NULL;
313 }
314 static int colortransform_setattr(PyObject * self, char* a, PyObject* o)
315 {
316     return 0;
317 }
318 CXFORM colortransform_getCXForm(PyObject*self)
319 {
320     CXFormObject*cxform= 0;
321     if (!PyArg_Parse(self, "O!", &CXFormClass, &cxform)) {
322         CXFORM dummy;
323         memset(&dummy, 0, sizeof(dummy));
324         mylog("Error: wrong type for function color_getRGBA");
325         return dummy;
326     }
327     return cxform->cxform;
328 }
329 void colortransform_dealloc(PyObject* self)
330 {
331     mylog("-%08x(%d) colortransform_dealloc", self, self->ob_refcnt);
332     PyObject_Del(self);
333 }
334 PyTypeObject CXFormClass = 
335 {
336     PyObject_HEAD_INIT(NULL)
337     0,
338     tp_name: "ColorTransform",
339     tp_basicsize: sizeof(CXFormObject),
340     tp_itemsize: 0,
341     tp_dealloc: colortransform_dealloc,
342     tp_print: 0,
343     tp_getattr: colortransform_getattr,
344     tp_setattr: colortransform_setattr,
345 };
346 //----------------------------------------------------------------------------
347 typedef struct {
348     PyObject_HEAD
349     GRADIENT gradient;
350 } GradientObject;
351
352 PyObject* f_Gradient(PyObject* self, PyObject* args, PyObject* kwargs)
353 {
354     return NULL;
355 }
356 static PyObject* gradient_getattr(PyObject * self, char* a)
357 {
358     return NULL;
359 }
360 static int gradient_setattr(PyObject * self, char* a, PyObject* o)
361 {
362     return 0;
363 }
364 GRADIENT gradient_getGradient(PyObject*self)
365 {
366     GradientObject*gradient = 0;
367     if (!PyArg_Parse(self, "O!", &gradient, &gradient)) {
368         GRADIENT dummy;
369         memset(&dummy, 0, sizeof(dummy));
370         mylog("Error: wrong type for function color_getRGBA");
371         return dummy;
372     }
373     return gradient->gradient;
374 }
375 void gradient_dealloc(PyObject* self)
376 {
377     mylog("-%08x(%d) gradient_dealloc", self, self->ob_refcnt);
378     PyObject_Del(self);
379 }
380 PyTypeObject GradientClass = 
381 {
382     PyObject_HEAD_INIT(NULL)
383     0,
384     tp_name: "Gradient",
385     tp_basicsize: sizeof(GradientObject),
386     tp_itemsize: 0,
387     tp_dealloc: gradient_dealloc,
388     tp_print: 0,
389     tp_getattr: gradient_getattr,
390     tp_setattr: gradient_setattr,
391 };
392 //----------------------------------------------------------------------------
393
394 static PyMethodDef primitive_methods[] = 
395 {
396     {"Color", (PyCFunction)f_Color, METH_KEYWORDS, "Create a new color object."},
397     {"Gradient", (PyCFunction)f_Gradient, METH_KEYWORDS, "Create a new gradient object."},
398     {"ColorTransform", (PyCFunction)f_ColorTransform, METH_KEYWORDS, "Create a new colortransform object."},
399     {"Matrix", (PyCFunction)f_Matrix, METH_KEYWORDS, "Create a new matrix object."},
400     {"BBox", (PyCFunction)f_BBox, METH_KEYWORDS, "Create a new bounding box object."},
401     {NULL, NULL, 0, NULL}
402 };
403
404 PyMethodDef* primitive_getMethods()
405 {
406     GradientClass.ob_type = &PyType_Type;
407     CXFormClass.ob_type = &PyType_Type;
408     BBoxClass.ob_type = &PyType_Type;
409     MatrixClass.ob_type = &PyType_Type;
410     return primitive_methods;
411 }
412
413