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