e70f28d8ace0bddb5cb3cf82e41e66976136fd3b
[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 PyObject* f_BBox2(SRECT box)
144 {
145     BBoxObject* bbox;
146     bbox = PyObject_New(BBoxObject, &BBoxClass);
147     bbox->bbox = box;
148     return (PyObject*)bbox;
149 }
150 static PyObject* bbox_getattr(PyObject * self, char* a)
151 {
152     BBoxObject*bbox = (BBoxObject*)self;
153     if(!strcmp(a, "xmin")) {
154         return Py_BuildValue("f", bbox->bbox.xmin/20.0);
155     } else if(!strcmp(a, "ymin")) {
156         return Py_BuildValue("f", bbox->bbox.ymin/20.0);
157     } else if(!strcmp(a, "xmax")) {
158         return Py_BuildValue("f", bbox->bbox.xmax/20.0);
159     } else if(!strcmp(a, "ymax")) {
160         return Py_BuildValue("f", bbox->bbox.ymax/20.0);
161     }
162     return NULL;
163 }
164 static int bbox_setattr(PyObject * self, char* a, PyObject* o)
165 {
166     BBoxObject*bbox= (BBoxObject*)self;
167     if(!strcmp(a, "xmin")) {
168         float xmin;
169         if (!PyArg_Parse(o, "i", &xmin)) goto err;
170         bbox->bbox.xmin = (int)(xmin*20);
171         return 0;
172     } else if(!strcmp(a, "ymin")) {
173         float ymin;
174         if (!PyArg_Parse(o, "i", &ymin)) goto err;
175         bbox->bbox.ymin = (int)(ymin*20);
176         return 0;
177     } else if(!strcmp(a, "xmax")) {
178         float xmax;
179         if (!PyArg_Parse(o, "i", &xmax)) goto err;
180         bbox->bbox.xmax = (int)(xmax*20);
181         return 0;
182     } else if(!strcmp(a, "ymax")) {
183         float ymax;
184         if (!PyArg_Parse(o, "i", &ymax)) goto err;
185         bbox->bbox.ymax = (int)(ymax*20);
186         return 0;
187     } 
188 err:
189     mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
190     return 1;
191 }
192 void bbox_dealloc(PyObject* self)
193 {
194     mylog("-%08x(%d) bbox_dealloc\n", (int)self, self->ob_refcnt);
195     PyObject_Del(self);
196 }
197 SRECT bbox_getSRECT(PyObject*self)
198 {
199     BBoxObject*bbox= 0;
200     if (!PyArg_Parse(self, "O!", &BBoxClass, &bbox)) {
201         SRECT dummy;
202         memset(&dummy, 0, sizeof(dummy));
203         mylog("Error: wrong type for function color_getRGBA");
204         return dummy;
205     }
206     return bbox->bbox;
207 }
208 PyTypeObject BBoxClass = 
209 {
210     PyObject_HEAD_INIT(NULL)
211     0,
212     tp_name: "BBox",
213     tp_basicsize: sizeof(BBoxObject),
214     tp_itemsize: 0,
215     tp_dealloc: bbox_dealloc,
216     tp_print: 0,
217     tp_getattr: bbox_getattr,
218     tp_setattr: bbox_setattr,
219 };
220 SRECT bbox_getBBox(PyObject*self);
221 //----------------------------------------------------------------------------
222 typedef struct {
223     PyObject_HEAD
224     MATRIX matrix;
225 } MatrixObject;
226
227 PyObject* f_Matrix(PyObject* _self, PyObject* args, PyObject* kwargs)
228 {
229     PyObject*self = (PyObject*)PyObject_New(MatrixObject, &MatrixClass);
230     MatrixObject*matrix = (MatrixObject*)self;
231     mylog("+%08x(%d) f_Matrix", self, self->ob_refcnt);
232     static char *kwlist[] = {"x", "y", "scale", "rotate", "pivotx", "pivoty", NULL};
233     float x=0,y=0,scale=1.0,rotate=0,pivotx,pivoty;
234     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ffffff", kwlist, &x,&y,&scale,&rotate,&pivotx,&pivoty))
235         return NULL;
236     mylog(" %08x(%d) f_Matrix: x=%f y=%f scale=%f rotate=%f", self, self->ob_refcnt, x,y,scale,rotate);
237     swf_GetMatrix(0, &matrix->matrix);
238
239     matrix->matrix.tx = (int)(x*20);
240     matrix->matrix.ty = (int)(y*20);
241
242     if(!rotate) {
243         matrix->matrix.sx = (int)(scale*65536);
244         matrix->matrix.sy = (int)(scale*65536);
245     } else {
246         matrix->matrix.sx = (int)(scale*cos(rotate)*65536);
247         matrix->matrix.sy = (int)(scale*cos(rotate)*65536);
248         matrix->matrix.r0 = (int)(scale*sin(rotate)*65536);
249         matrix->matrix.r1 = (int)(-scale*sin(rotate)*65536);
250     }
251     if(pivotx || pivoty) {
252         SPOINT p,d;
253         p.x = (int)(pivotx*20);
254         p.y = (int)(pivoty*20);
255         p = swf_TurnPoint(p, &matrix->matrix);
256         matrix->matrix.tx += matrix->matrix.tx-p.x;
257         matrix->matrix.ty += matrix->matrix.ty-p.y;
258     }
259
260     /* TODO: rotate */
261     return self;
262 }
263 static PyObject* matrix_getattr(PyObject * self, char* a)
264 {
265     PY_ASSERT_TYPE(self,&MatrixClass);
266     return NULL;
267 }
268 static int matrix_setattr(PyObject * self, char* a, PyObject* o)
269 {
270     PY_ASSERT_TYPE(self,&MatrixClass);
271     return 0;
272 }
273 MATRIX matrix_getMatrix(PyObject*self)
274 {
275     mylog(" %08x(%d) matrix_getMatrix", self, self->ob_refcnt);
276     PY_ASSERT_TYPE(self,&MatrixClass);
277     MatrixObject*matrix = (MatrixObject*)self;
278     return matrix->matrix;
279 }
280 void matrix_dealloc(PyObject* self)
281 {
282     mylog("-%08x(%d) matrix_dealloc", self, self->ob_refcnt);
283     PyObject_Del(self);
284 }
285 //SPOINT swf_TurnPoint(SPOINT p, MATRIX* m);
286 //SRECT swf_TurnRect(SRECT r, MATRIX* m);
287 PyTypeObject MatrixClass = 
288 {
289     PyObject_HEAD_INIT(NULL)
290     0,
291     tp_name: "Matrix",
292     tp_basicsize: sizeof(MatrixObject),
293     tp_itemsize: 0,
294     tp_dealloc: matrix_dealloc,
295     tp_print: 0,
296     tp_getattr: matrix_getattr,
297     tp_setattr: matrix_setattr,
298     tp_compare: 0,
299     tp_repr: 0,
300     tp_as_number: 0,
301     tp_as_sequence: 0,
302     tp_as_mapping: 0,
303     tp_hash: 0,     // dict(x)
304     tp_call: 0,     // x()
305     tp_str: 0       // str(x)
306 };
307 //----------------------------------------------------------------------------
308 typedef struct {
309     PyObject_HEAD
310     CXFORM cxform;
311 } CXFormObject;
312
313 PyObject* f_ColorTransform(PyObject* self, PyObject* args, PyObject* kwargs)
314 {
315     return NULL;
316 }
317 static PyObject* colortransform_getattr(PyObject * self, char* a)
318 {
319     return NULL;
320 }
321 static int colortransform_setattr(PyObject * self, char* a, PyObject* o)
322 {
323     return 0;
324 }
325 CXFORM colortransform_getCXForm(PyObject*self)
326 {
327     CXFormObject*cxform= 0;
328     if (!PyArg_Parse(self, "O!", &CXFormClass, &cxform)) {
329         CXFORM dummy;
330         memset(&dummy, 0, sizeof(dummy));
331         mylog("Error: wrong type for function color_getRGBA");
332         return dummy;
333     }
334     return cxform->cxform;
335 }
336 void colortransform_dealloc(PyObject* self)
337 {
338     mylog("-%08x(%d) colortransform_dealloc", self, self->ob_refcnt);
339     PyObject_Del(self);
340 }
341 PyTypeObject CXFormClass = 
342 {
343     PyObject_HEAD_INIT(NULL)
344     0,
345     tp_name: "ColorTransform",
346     tp_basicsize: sizeof(CXFormObject),
347     tp_itemsize: 0,
348     tp_dealloc: colortransform_dealloc,
349     tp_print: 0,
350     tp_getattr: colortransform_getattr,
351     tp_setattr: colortransform_setattr,
352 };
353 //----------------------------------------------------------------------------
354 typedef struct {
355     PyObject_HEAD
356     GRADIENT gradient;
357 } GradientObject;
358
359 PyObject* f_Gradient(PyObject* self, PyObject* args, PyObject* kwargs)
360 {
361     return NULL;
362 }
363 static PyObject* gradient_getattr(PyObject * self, char* a)
364 {
365     return NULL;
366 }
367 static int gradient_setattr(PyObject * self, char* a, PyObject* o)
368 {
369     return 0;
370 }
371 GRADIENT gradient_getGradient(PyObject*self)
372 {
373     GradientObject*gradient = 0;
374     if (!PyArg_Parse(self, "O!", &gradient, &gradient)) {
375         GRADIENT dummy;
376         memset(&dummy, 0, sizeof(dummy));
377         mylog("Error: wrong type for function color_getRGBA");
378         return dummy;
379     }
380     return gradient->gradient;
381 }
382 void gradient_dealloc(PyObject* self)
383 {
384     mylog("-%08x(%d) gradient_dealloc", self, self->ob_refcnt);
385     PyObject_Del(self);
386 }
387 PyTypeObject GradientClass = 
388 {
389     PyObject_HEAD_INIT(NULL)
390     0,
391     tp_name: "Gradient",
392     tp_basicsize: sizeof(GradientObject),
393     tp_itemsize: 0,
394     tp_dealloc: gradient_dealloc,
395     tp_print: 0,
396     tp_getattr: gradient_getattr,
397     tp_setattr: gradient_setattr,
398 };
399 //----------------------------------------------------------------------------
400
401 static PyMethodDef primitive_methods[] = 
402 {
403     {"Color", (PyCFunction)f_Color, METH_KEYWORDS, "Create a new color object."},
404     {"Gradient", (PyCFunction)f_Gradient, METH_KEYWORDS, "Create a new gradient object."},
405     {"ColorTransform", (PyCFunction)f_ColorTransform, METH_KEYWORDS, "Create a new colortransform object."},
406     {"Matrix", (PyCFunction)f_Matrix, METH_KEYWORDS, "Create a new matrix object."},
407     {"BBox", (PyCFunction)f_BBox, METH_KEYWORDS, "Create a new bounding box object."},
408     {NULL, NULL, 0, NULL}
409 };
410
411 PyMethodDef* primitive_getMethods()
412 {
413     GradientClass.ob_type = &PyType_Type;
414     CXFormClass.ob_type = &PyType_Type;
415     BBoxClass.ob_type = &PyType_Type;
416     MatrixClass.ob_type = &PyType_Type;
417     return primitive_methods;
418 }
419
420