ed089311338f5ee3a4e1b02cee4bc2f4ad82de9b
[swftools.git] / lib / python / tag.c
1 #include <Python.h>
2 #undef HAVE_STAT
3 #include "../rfxswf.h"
4 #include "../log.h"
5 #include "./pyutils.h"
6 #include "primitives.h"
7 #include "action.h"
8 #include "tag.h"
9
10 //----------------------------------------------------------------------------
11 typedef struct {
12     PyObject_HEAD
13     TAG*tag;
14     /* ST_DEFINEFONT*/
15     SWFFONT* font;
16     /* ST_PLACEOBJECT, ST_PLACEOBJECT2*/
17     SWFPLACEOBJECT* placeobject;
18     PyObject* character;
19 } TagObject;
20
21 static void tag_dealloc(PyObject * self)
22 {
23     TagObject*tag = (TagObject*)self;
24     mylog("tag_dealoc %08x(%d)\n", (int)self, self->ob_refcnt);
25     if(tag->placeobject) {
26         swf_PlaceObjectFree(tag->placeobject);
27         tag->placeobject = 0;
28     }
29     if(tag->font) {
30         swf_FontFree(tag->font);
31         tag->font = 0;
32     }
33     if(tag->character) {
34         Py_DECREF(tag->character);
35         tag->character = 0;
36     }
37     PyObject_Del(self);
38 }
39 //----------------------------------------------------------------------------
40 static PyObject* tag_setU8(PyObject * self, PyObject*other)
41 {
42     return NULL;
43 }
44 //----------------------------------------------------------------------------
45 static PyObject* tag_setbackgroundcolor_getrgb(PyObject * self, PyObject*other)
46 {
47     TagObject*tag = (TagObject*)self;
48     int r,g,b;
49     r = tag->tag->data[0];
50     g = tag->tag->data[1];
51     b = tag->tag->data[2];
52     return Py_BuildValue("(iii)", r,g,b);
53 }
54 //----------------------------------------------------------------------------
55
56 static struct tagfunctions {
57     int id;
58     PyMethodDef f[8];
59 } tagfunctions[] =
60 {
61  { 
62    ST_SETBACKGROUNDCOLOR, 
63    {{"getRGB", tag_setbackgroundcolor_getrgb, METH_VARARGS, "get's the color set by this tag"},
64     {NULL, NULL, 0, NULL}
65    }
66  }
67 };
68 static PyMethodDef common_tagfunctions[] =
69 {{"setU8", tag_setU8, METH_VARARGS, "sets a byte to the tag data"},
70  {NULL, NULL, 0, NULL}
71 };
72
73 static PyObject* tag_getattr(PyObject * self, char* a)
74 {
75     TagObject*tag = (TagObject*)self;
76     PyObject* ret = NULL;
77     int id =  tag->tag->id;
78     int t;
79
80     /* -- fields -- */
81     if(!strcmp(a, "id")) {
82         return Py_BuildValue("i", id);
83     }
84     if(!strcmp(a, "name")) {
85         char* name = swf_TagGetName(tag->tag);
86         return Py_BuildValue("s", name);
87     }
88     /* ------------ */
89    
90     /* search for a tag specific function */
91     for(t=0;t<sizeof(tagfunctions)/sizeof(tagfunctions[0]);t++)
92     {
93         if(id==tagfunctions[t].id) {
94             mylog("tag_getattr: id %d found\n", id);
95             ret = Py_FindMethod(tagfunctions[t].f, self, a);
96             if(!ret) return ret;
97             ret = FindMethodMore(ret, common_tagfunctions, self, a);
98             mylog("tag_getattr %08x(%d) %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
99             return ret;
100         }
101     }
102    
103     ret = Py_FindMethod(common_tagfunctions, self, a);
104
105     mylog("tag_getattr %08x(%d) %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
106     return ret;
107 }
108 //----------------------------------------------------------------------------
109 //                     Tag Contructors
110 //----------------------------------------------------------------------------
111 PyObject* tag_new()
112 {
113     TagObject*tag = PyObject_New(TagObject, &TagClass);
114     tag->font = 0;
115     tag->character = 0;
116     tag->placeobject = 0;
117     tag->tag = 0;
118     return (PyObject*)tag;
119 }
120 PyObject* tag_new2(TAG*_tag)
121 {
122     TagObject*tag = PyObject_New(TagObject, &TagClass);
123     tag->font = 0;
124     tag->character = 0;
125     tag->placeobject = 0;
126     tag->tag = _tag;
127     return (PyObject*)tag;
128 }
129
130 static PyObject* f_SetBackgroundColor(PyObject* self, PyObject* args, PyObject* kwargs)
131 {
132     static char *kwlist[] = {"color", NULL};
133     int r=0,g=0,b=0;
134     TagObject*tag;
135     PyObject*color;
136
137     /* 1st try- copy constructor */
138     if(!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &ColorClass, &color)) {
139         /* 2nd try- color's contructor */
140         color = f_Color(NULL, args, kwargs);
141     }
142     if(!color)
143         return NULL;
144
145     tag = (TagObject*)tag_new();
146     tag->tag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR);
147     RGBA rgba = color_getRGBA(color);
148     swf_SetU8(tag->tag, rgba.r);
149     swf_SetU8(tag->tag, rgba.g);
150     swf_SetU8(tag->tag, rgba.b);
151     mylog("SetBackgroundColor(%02x,%02x,%02x) %08x -> %08x\n", rgba.r, rgba.g, rgba.b, (int)self, tag);
152     return (PyObject*)tag;
153 }
154 //----------------------------------------------------------------------------
155 static PyObject* f_DefineFont(PyObject* self, PyObject* args, PyObject* kwargs)
156 {
157     static char *kwlist[] = {"filename", NULL};
158     char*filename = 0;
159     TagObject*tag;
160     SWFFONT* font;
161
162     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &filename))
163         return NULL;
164
165     font = swf_LoadFont(filename);
166     mylog("font=%08x",font);
167     if(!font) {
168         PyErr_SetString(PyExc_Exception, setError("Could not load %s", filename));
169         return NULL;
170     }
171
172     tag = (TagObject*)tag_new();
173     tag->font = font;
174     tag->tag = swf_InsertTag(0, ST_DEFINEFONT2);
175     tag->font->id = 0xabcd; // swf_SetU16(id);
176     swf_FontSetDefine2(tag->tag, tag->font); // TODO: should this be done later, in taglist?
177     mylog("DefineFont %08x -> %08x\n", (int)self, (int)tag);
178     return (PyObject*)tag;
179 }
180 //----------------------------------------------------------------------------
181 static PyObject* f_Protect(PyObject* self, PyObject* args, PyObject* kwargs)
182 {
183     static char *kwlist[] = {"password", NULL};
184     char*password = 0;
185     TagObject*tag;
186
187     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &password))
188         return NULL;
189
190     tag = (TagObject*)tag_new();
191     tag->tag = swf_InsertTag(0, ST_PROTECT);
192     if(password) {
193         swf_SetPassword(tag->tag, password);
194     }
195     mylog("f_Protect %08x -> %08x\n", (int)self, (int)tag);
196     return (PyObject*)tag;
197 }
198 //----------------------------------------------------------------------------
199 static PyObject* f_DefineText(PyObject* self, PyObject* args, PyObject* kwargs)
200 {
201     static char *kwlist[] = {"font", "text", "size", "color", NULL};
202     TagObject*tag;
203     char*text = 0;
204     int textlen = 0;
205     PyObject*unicode16;
206     PyObject*unicode8;
207     int size = 0;
208     RGBA rgba = {0,0,0,255};
209     PyObject*color = 0;
210     TagObject*font = 0;
211     SRECT r;
212     
213     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!u#i|O!", kwlist, &TagClass, &font, &text, &textlen, &size, &ColorClass, &color))
214         return NULL;
215     
216     unicode16 = PyUnicode_DecodeUTF16(text, textlen*2, NULL, NULL);
217     unicode8 = PyUnicode_AsUTF8String(unicode16);
218     text = PyString_AS_STRING(unicode8);
219
220     if(color)
221         rgba = color_getRGBA(color);
222
223     mylog("DefineText: text = %s", text);
224     
225     tag = (TagObject*)tag_new();
226     tag ->tag= swf_InsertTag(0, ST_DEFINETEXT2);
227     swf_SetU16(tag->tag, /*ID*/0);
228     r = swf_SetDefineText(tag->tag, font->font, &rgba, text, size);
229     mylog("DefineText %08x -> %08x\n", (int)self, (int)tag);
230     return (PyObject*)tag;
231 }
232 //----------------------------------------------------------------------------
233 static PyObject* f_PlaceObject(PyObject* self, PyObject* args, PyObject* kwargs)
234 {
235     static char *kwlist[] = {"character", "depth", "matrix", "colortransform", "ratio", "name", "clipdepth", "action", NULL};
236     TagObject*tag;
237     
238     TagObject*character = 0;
239     int depth;
240     int clipdepth = 0;
241     PyObject*matrix = 0;
242     PyObject*cxform = 0;
243     PyObject*action = 0;
244     int ratio = 0;
245     char* name = 0;
246     SWFPLACEOBJECT* po;
247     po = malloc(sizeof(SWFPLACEOBJECT));
248     memset(po, 0, sizeof(SWFPLACEOBJECT));
249
250     swf_GetPlaceObject(0, po);
251
252     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!i|O!O!isiO!", kwlist, 
253                 &TagClass, &character, 
254                 &depth, 
255                 &MatrixClass, &matrix, 
256                 &CXFormClass, &cxform,
257                 &ratio,
258                 &name,
259                 &clipdepth,
260                 &action
261                 ))
262         return NULL;
263     po->depth = depth;
264     po->id = /*ID*/ 0;
265     po->clipdepth = clipdepth;
266     po->ratio = ratio;
267     po->name = name;
268     if(clipdepth) po->matrix = matrix_getMatrix(matrix);
269     if(cxform) po->cxform = colortransform_getCXForm(cxform);
270     if(action) po->actions = action_getAction(action);
271
272     tag = (TagObject*)tag_new();
273     tag->placeobject = po;
274     Py_INCREF(character);
275     tag->character = (PyObject*)character;
276     tag->tag= swf_InsertTag(0, ST_PLACEOBJECT2);
277     swf_SetPlaceObject(tag->tag, po);
278     mylog("PlaceObject %08x -> %08x\n", (int)self, (int)tag);
279     return (PyObject*)tag;
280 }
281
282 TAG* tag_getTAG(PyObject*self)
283 {
284     // TODO: checking!
285     return ((TagObject*)self)->tag;
286 }
287
288 PyTypeObject TagClass = 
289 {
290     PyObject_HEAD_INIT(NULL)
291     0,
292     tp_name: "Tag",
293     tp_basicsize: sizeof(TagObject),
294     tp_itemsize: 0,
295     tp_dealloc: tag_dealloc,
296     tp_print: 0,
297     tp_getattr: tag_getattr,
298 };
299 static PyMethodDef TagMethods[] = 
300 {
301     /* TAGS */
302     {"SetBackgroundColor", (PyCFunction)f_SetBackgroundColor, METH_KEYWORDS, "Create a SetBackGroundColor Tag."},
303     {"Protect", (PyCFunction)f_Protect, METH_KEYWORDS, "Create a Protect Tag."},
304     {"DefineFont", (PyCFunction)f_DefineFont, METH_KEYWORDS, "Create a DefineFont Tag."},
305     {"DefineText", (PyCFunction)f_DefineText, METH_KEYWORDS, "Create a DefineText Tag."},
306     {"PlaceObject", (PyCFunction)f_PlaceObject, METH_KEYWORDS, "Create a PlaceObject Tag."},
307     {NULL, NULL, 0, NULL}
308 };
309 PyMethodDef* tag_getMethods()
310 {
311     TagClass.ob_type = &PyType_Type;
312     return TagMethods;
313 }
314