6 #include "primitives.h"
11 //----------------------------------------------------------------------------
15 typedef struct _tag_internals
18 int (*parse)(struct _TagObject*);
19 int (*fillTAG)(struct _TagObject*);
20 void (*dealloc)(struct _TagObject*);
22 PyMethodDef* tagfunctions;
25 typedef struct _TagObject {
30 tag_internals_t internals;
33 //----------------------------------------------------------------------------
35 PyObject* tag_new(tag_internals_t*tag_internals);
37 typedef struct _font_internal
41 staticforward tag_internals_t font_tag;
43 static int font_parse(TagObject*self)
45 font_internal_t*font = (font_internal_t*)self->internals.data;
47 PyErr_SetString(PyExc_Exception, setError("Font parsing not implemented yet"));
50 static void font_dealloc(TagObject*self)
52 font_internal_t*font = (font_internal_t*)self->internals.data;
54 swf_FontFree(font->font);
58 static int font_fillTAG(TagObject*self)
60 font_internal_t*fi = (font_internal_t*)self->internals.data;
63 self->tag = swf_InsertTag(0, ST_DEFINEFONT2);
64 swf_FontSetDefine2(self->tag, fi->font);
67 static PyObject* f_DefineFont(PyObject* self, PyObject* args, PyObject* kwargs)
69 static char *kwlist[] = {"filename", NULL};
74 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &filename))
77 font = swf_LoadFont(filename);
79 PyErr_SetString(PyExc_Exception, setError("Could not load %s", filename));
83 tag = (TagObject*)tag_new(&font_tag);
84 font_internal_t*fi = (font_internal_t*)tag->internals.data;
87 return (PyObject*)tag;
89 static SWFFONT* font_getSWFFONT(PyObject*self)
91 PY_ASSERT_TYPE(self, &TagClass);
92 TagObject*tag = (TagObject*)self;
93 font_internal_t*fi = (font_internal_t*)tag->internals.data;
96 static tag_internals_t font_tag =
98 size: sizeof(font_internal_t),
100 fillTAG: font_fillTAG,
101 dealloc: font_dealloc,
104 //----------------------------------------------------------------------------
106 typedef struct _placeobject_internal
109 } placeobject_internal_t;
110 staticforward tag_internals_t placeobject_tag;
112 static void po_dealloc(TagObject*self)
114 placeobject_internal_t*pi = (placeobject_internal_t*)self->internals.data;
116 swf_PlaceObjectFree(pi->po);
120 static int po_parse(TagObject*self)
122 placeobject_internal_t*pi = (placeobject_internal_t*)self->internals.data;
124 PyErr_SetString(PyExc_Exception, setError("Font parsing not implemented yet"));
127 static int po_fillTAG(TagObject*self)
129 placeobject_internal_t*pi = (placeobject_internal_t*)self->internals.data;
130 self->tag = swf_InsertTag(0, ST_PLACEOBJECT2);
131 swf_SetPlaceObject(self->tag, pi->po);
134 static PyObject* f_PlaceObject(PyObject* self, PyObject* args, PyObject* kwargs)
136 static char *kwlist[] = {"character", "depth", "matrix", "colortransform", "ratio", "name", "clipdepth", "action", NULL};
139 TagObject*character = 0;
148 po = malloc(sizeof(SWFPLACEOBJECT));
149 memset(po, 0, sizeof(SWFPLACEOBJECT));
151 swf_GetPlaceObject(0, po);
153 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!i|O!O!isiO!", kwlist,
154 &TagClass, &character,
156 &MatrixClass, &matrix,
157 &CXFormClass, &cxform,
161 &ActionClass, &action
166 po->clipdepth = clipdepth;
169 if(clipdepth) po->clipdepth = clipdepth;
170 if(matrix) po->matrix = matrix_getMatrix(matrix);
171 if(cxform) po->cxform = colortransform_getCXForm(cxform);
172 if(action) po->actions = action_getAction(action);
174 tag = (TagObject*)tag_new(&placeobject_tag);
175 placeobject_internal_t*pi = (placeobject_internal_t*)tag->internals.data;
177 pi->po->id = tagmap_add(tag->tagmap,(PyObject*)character);
179 mylog("+%08x(%d) PlaceObject %08x(%d)\n", (int)tag, tag->ob_refcnt, character, character->ob_refcnt);
181 return (PyObject*)tag;
183 static tag_internals_t placeobject_tag =
185 size: sizeof(placeobject_internal_t),
191 //----------------------------------------------------------------------------
192 staticforward tag_internals_t bgcolor_tag;
193 static PyObject* tag_setbackgroundcolor_getrgb(PyObject * self, PyObject*other)
195 TagObject*tag = (TagObject*)self;
197 r = tag->tag->data[0];
198 g = tag->tag->data[1];
199 b = tag->tag->data[2];
200 return Py_BuildValue("(iii)", r,g,b);
202 static PyMethodDef setbgcolor_methods[] =
203 {{"getRGB", tag_setbackgroundcolor_getrgb, METH_VARARGS, "get's the color set by this tag"},
204 {NULL, NULL, 0, NULL}
206 static PyObject* f_SetBackgroundColor(PyObject* self, PyObject* args, PyObject* kwargs)
208 static char *kwlist[] = {"color", NULL};
213 tag = (TagObject*)tag_new(&bgcolor_tag);
215 /* 1st try- copy constructor */
216 if(!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &ColorClass, &color)) {
217 /* 2nd try- color's contructor */
218 color = f_Color(NULL, args, kwargs);
223 tag->tag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR);
224 RGBA rgba = color_getRGBA(color);
225 swf_SetU8(tag->tag, rgba.r);
226 swf_SetU8(tag->tag, rgba.g);
227 swf_SetU8(tag->tag, rgba.b);
228 mylog(" %08x(%d) SetBackgroundColor(%02x,%02x,%02x) (colorobj=%08x(%d))\n", (int)tag, tag->ob_refcnt, rgba.r, rgba.g, rgba.b, color, color->ob_refcnt);
229 return (PyObject*)tag;
231 static tag_internals_t bgcolor_tag =
237 tagfunctions: setbgcolor_methods
239 //----------------------------------------------------------------------------
240 staticforward tag_internals_t protect_tag;
241 static PyObject* f_Protect(PyObject* self, PyObject* args, PyObject* kwargs)
243 static char *kwlist[] = {"password", NULL};
246 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &password))
249 TagObject*tag = (TagObject*)tag_new(&protect_tag);
250 tag->tag = swf_InsertTag(0, ST_PROTECT);
252 swf_SetPassword(tag->tag, password);
254 mylog("+%08x(%d) f_Protect", (int)tag, tag->ob_refcnt);
255 return (PyObject*)tag;
257 static tag_internals_t protect_tag =
265 //----------------------------------------------------------------------------
266 staticforward tag_internals_t text_tag;
268 typedef struct _text_internal // not used yet
276 staticforward tag_internals_t placeobject_tag;
278 static int text_fillTAG(TagObject*self) //not used yet
280 text_internal_t*ti = (text_internal_t*)self->internals.data;
281 self->tag= swf_InsertTag(0, ST_DEFINETEXT2);
282 swf_SetU16(self->tag, /*ID*/0);
283 SRECT r = swf_SetDefineText(self->tag, ti->swffont, &ti->rgba, ti->text, ti->size);
286 static PyObject* f_DefineText(PyObject* self, PyObject* args, PyObject* kwargs)
288 static char *kwlist[] = {"font", "text", "size", "color", NULL};
295 RGBA rgba = {255,0,0,0};
300 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!u#i|O!", kwlist, &TagClass, &font, &text, &textlen, &size, &ColorClass, &color))
303 unicode16 = PyUnicode_DecodeUTF16(text, textlen*2, NULL, NULL);
304 unicode8 = PyUnicode_AsUTF8String(unicode16);
305 text = PyString_AS_STRING(unicode8);
308 rgba = color_getRGBA(color);
310 mylog("DefineText: text = %s", text);
312 tag = (TagObject*)tag_new(&text_tag);
313 text_internal_t*ti = (text_internal_t*)tag->internals.data;
315 SWFFONT* swffont = font_getSWFFONT(font);
316 int font_id = tagmap_add(tag->tagmap, font); // add dependency on font
317 swffont->id = font_id; // for swf_SetDefineText
319 /* todo: remove, store data in ti */
320 tag->tag= swf_InsertTag(0, ST_DEFINETEXT2);
321 swf_SetU16(tag->tag, /*ID*/0);
322 r = swf_SetDefineText(tag->tag, swffont, &rgba, text, size);
323 mylog("+%08x(%d) DefineText tag=%08x \n", (int)tag, tag->ob_refcnt);
325 //Py_DECREF(unicode16);
326 //Py_DECREF(unicode8);
329 return (PyObject*)tag;
331 static tag_internals_t text_tag =
333 size: sizeof(text_internal_t),
335 fillTAG: text_fillTAG,
339 //----------------------------------------------------------------------------
340 static PyMethodDef generic_methods[] =
342 {NULL, NULL, 0, NULL}
344 static tag_internals_t generic_tag =
350 tagfunctions: generic_methods
352 //----------------------------------------------------------------------------
356 tag_internals_t*spec;
358 {ST_PLACEOBJECT,&placeobject_tag},
359 {ST_PLACEOBJECT2,&placeobject_tag},
360 {ST_SETBACKGROUNDCOLOR,&bgcolor_tag},
361 {ST_DEFINEFONT,&font_tag},
362 {ST_PROTECT,&protect_tag},
363 {ST_DEFINETEXT,&text_tag},
366 //----------------------------------------------------------------------------
367 static void tag_dealloc(PyObject * self)
369 TagObject*tag = (TagObject*)self;
371 mylog("-%08x(%d) tag_dealoc [%s]\n", (int)self, self->ob_refcnt, swf_TagGetName(tag->tag));
373 mylog("-%08x(%d) tag_dealoc [?]\n", (int)self, self->ob_refcnt);
374 if(tag->internals.dealloc) {
375 if(!tag->internals.data)
376 mylog("-%08x(%d) tag_dealoc: Warning: calling dealloc without any data(?)\n", (int)self, self->ob_refcnt);
377 tag->internals.dealloc(tag);
379 if(tag->internals.data) {
380 free(tag->internals.data);
381 tag->internals.data = 0;
384 swf_DeleteTag(tag->tag);
387 Py_DECREF(tag->tagmap);
391 //----------------------------------------------------------------------------
392 static PyObject* tag_setU8(PyObject * self, PyObject*other)
396 //----------------------------------------------------------------------------
397 static PyMethodDef common_tagfunctions[] =
398 {{"setU8", tag_setU8, METH_VARARGS, "sets a byte to the tag data"},
399 {NULL, NULL, 0, NULL}
402 static int fillTAG(PyObject*self)
404 TagObject*tag = (TagObject*)self;
407 if(!tag->internals.fillTAG) {
408 PyErr_SetString(PyExc_Exception, setError("No way to fill TAG with data"));
411 if(!tag->internals.fillTAG(tag)) {
412 return 0; // pass through exception
415 PyErr_SetString(PyExc_Exception, setError("Couldn't fill tag"));
420 static PyObject* tag_getattr(PyObject * self, char* a)
422 TagObject*tag = (TagObject*)self;
423 PyObject* ret = NULL;
427 if(!strcmp(a, "id")) {
430 return Py_BuildValue("i", tag->tag->id);
432 if(!strcmp(a, "name")) {
435 char* name = swf_TagGetName(tag->tag);
436 return Py_BuildValue("s", name);
439 /* search for a tag specific function */
440 if(tag->internals.tagfunctions) {
441 mylog(" %08x(%d) tag_getattr: tag has specific functions\n", (int)self, self->ob_refcnt);
442 ret = Py_FindMethod(tag->internals.tagfunctions, self, a);
444 ret = FindMethodMore(ret, common_tagfunctions, self, a);
445 mylog(" %08x(%d) tag_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
449 ret = Py_FindMethod(common_tagfunctions, self, a);
451 mylog(" %08x(%d) tag_getattr %s: %08x\n", (int)self, self->ob_refcnt, a, ret);
454 //----------------------------------------------------------------------------
456 //----------------------------------------------------------------------------
457 PyObject* tag_new(tag_internals_t*tag_internals)
459 TagObject*tag = PyObject_New(TagObject, &TagClass);
460 mylog("+%08x(%d) tag_new\n", (int)tag, tag->ob_refcnt);
461 memcpy(&tag->internals, tag_internals, sizeof(tag_internals_t));
462 if(tag->internals.size) {
463 tag->internals.data = malloc(tag->internals.size);
464 memset(tag->internals.data , 0, tag->internals.size);
466 tag->internals.data = 0;
469 tag->tagmap = tagmap_new();
471 return (PyObject*)tag;
473 PyObject* tag_new2(TAG*t, PyObject* tagmap)
475 TagObject*tag = PyObject_New(TagObject, &TagClass);
476 mylog("+%08x(%d) tag_new2 tag=%08x id=%d (%s)\n", (int)tag, tag->ob_refcnt, t, t->id, swf_TagGetName(t));
478 tag->tagmap = tagmap_new();
480 int num = swf_GetNumUsedIDs(t);
481 if(num) { // tag has dependencies
482 int * positions = malloc(num*sizeof(int));
483 swf_GetUsedIDs(t, positions);
486 int id = GET16(&t->data[positions[i]]);
487 PyObject*obj = tagmap_id2obj(tagmap, id);
489 PyErr_SetString(PyExc_Exception, setError("TagID %d not defined", id));
492 //mylog("+%08x(%d) tag_new2 handling id %d at %d/%d\n", (int)tag, tag->ob_refcnt, id, positions[i], t->len);
493 //mylog("+%08x(%d) tag_new2 add dependency %d to id %d, object %08x(%d)\n", (int)tag, tag->ob_refcnt, i, id, obj, obj->ob_refcnt);
494 tagmap_addMapping(tag->tagmap, id, obj);
499 tag->tag = swf_InsertTag(0, t->id);
500 swf_SetBlock(tag->tag, t->data, t->len);
503 while(tag_parsers[i].id>=0) {
504 if(tag_parsers[i].id == t->id) {
505 memcpy(&tag->internals, tag_parsers[i].spec, sizeof(tag_internals_t));
512 memcpy(&tag->internals, &generic_tag, sizeof(tag_internals_t));
514 if(tag->internals.size) {
515 tag->internals.data = malloc(tag->internals.size);
516 memset(tag->internals.data, 0, tag->internals.size);
518 tag->internals.data = 0;
520 return (PyObject*)tag;
522 //----------------------------------------------------------------------------
524 TAG* tag_getTAG(PyObject*self, TAG*prevTag, PyObject*tagmap)
526 TagObject*tag = (TagObject*)self;
530 mylog(" %08x(%d) tag_getTAG: tag=%08x id=%d (%s)", (int)self, self->ob_refcnt, tag->tag, tag->tag->id, swf_TagGetName(tag->tag));
532 TAG* t = swf_InsertTag(prevTag, tag->tag->id);
533 swf_SetBlock(t, tag->tag->data, tag->tag->len);
535 if(swf_isDefiningTag(t)) {
536 int newid = tagmap_add(tagmap, self);
537 swf_SetDefineID(t, newid);
540 int num = swf_GetNumUsedIDs(t);
541 if(num) { // tag has dependencies
542 int * positions = malloc(num*sizeof(int));
543 swf_GetUsedIDs(t, positions);
546 int id = GET16(&t->data[positions[i]]);
547 PyObject* obj = tagmap_id2obj(tag->tagmap, id);
549 PyErr_SetString(PyExc_Exception, setError("Internal error: id %d not known in taglist:"));
553 int newid = tagmap_obj2id(tagmap, obj);
554 PUT16(&t->data[positions[i]], newid);
560 PyObject* tag_getDependencies(PyObject*self)
562 TagObject*tag = (TagObject*)self;
563 mylog(" %08x(%d) tag_getDependencies\n", (int)self, self->ob_refcnt);
564 return tagmap_getObjectList(tag->tagmap);
566 int tag_print(PyObject * self, FILE * fi, int flags)
568 TagObject*tag = (TagObject*)self;
569 mylog(" %08x(%d) tag_print flags=%08x\n", (int)self, self->ob_refcnt, flags);
572 fprintf(fi, "tag-%08x-%d-%s", (int)tag->tag, tag->tag->id, swf_TagGetName(tag->tag));
575 PyTypeObject TagClass =
577 PyObject_HEAD_INIT(NULL)
580 tp_basicsize: sizeof(TagObject),
582 tp_dealloc: tag_dealloc,
584 tp_getattr: tag_getattr,
586 static PyMethodDef TagMethods[] =
589 {"SetBackgroundColor", (PyCFunction)f_SetBackgroundColor, METH_KEYWORDS, "Create a SetBackGroundColor Tag."},
590 {"Protect", (PyCFunction)f_Protect, METH_KEYWORDS, "Create a Protect Tag."},
591 {"DefineFont", (PyCFunction)f_DefineFont, METH_KEYWORDS, "Create a DefineFont Tag."},
592 {"DefineText", (PyCFunction)f_DefineText, METH_KEYWORDS, "Create a DefineText Tag."},
593 {"PlaceObject", (PyCFunction)f_PlaceObject, METH_KEYWORDS, "Create a PlaceObject Tag."},
594 {NULL, NULL, 0, NULL}
596 PyMethodDef* tag_getMethods()
598 TagClass.ob_type = &PyType_Type;