From 49062bcde61a1622b6e5605097beff11916cd07e Mon Sep 17 00:00:00 2001 From: kramm Date: Mon, 15 Sep 2003 16:15:59 +0000 Subject: [PATCH] python interface to rfxswflib - initial draft. --- lib/python/Makefile | 17 + lib/python/SWF.c | 803 +++++++++++++++++++++++++++++++++++++++++++++++ lib/python/action.c | 90 ++++++ lib/python/action.h | 38 +++ lib/python/mypython.c | 5 + lib/python/primitives.c | 236 ++++++++++++++ lib/python/primitives.h | 65 ++++ lib/python/pyutils.c | 66 ++++ lib/python/pyutils.h | 11 + 9 files changed, 1331 insertions(+) create mode 100644 lib/python/Makefile create mode 100644 lib/python/SWF.c create mode 100644 lib/python/action.c create mode 100644 lib/python/action.h create mode 100644 lib/python/mypython.c create mode 100644 lib/python/primitives.c create mode 100644 lib/python/primitives.h create mode 100644 lib/python/pyutils.c create mode 100644 lib/python/pyutils.h diff --git a/lib/python/Makefile b/lib/python/Makefile new file mode 100644 index 0000000..eb270dd --- /dev/null +++ b/lib/python/Makefile @@ -0,0 +1,17 @@ +all: mypython SWF.so + +primitives.o: primitives.c primitives.h + gcc -g -O2 -Wall -Wno-unused -fPIC -I/usr/include/python2.2 -c primitives.c -o primitives.o +pyutils.o: pyutils.c pyutils.h + gcc -g -O2 -Wall -Wno-unused -fPIC -I/usr/include/python2.2 -c pyutils.c -o pyutils.o +SWF.o: SWF.c pyutils.h primitives.h + gcc -g -O2 -Wall -Wno-unused -fPIC -I/usr/include/python2.2 -c SWF.c -o SWF.o + +SWF.so: primitives.o pyutils.o SWF.o + gcc -shared primitives.o SWF.o pyutils.o -o SWF.so -lpython2.2 ../librfxswf.a -ljpeg -lz + +mypython: mypython.c + gcc -I/usr/include/python2.2 mypython.c -o mypython -lpython2.2 + +test: SWF.so + python fonts.py diff --git a/lib/python/SWF.c b/lib/python/SWF.c new file mode 100644 index 0000000..a24a5f0 --- /dev/null +++ b/lib/python/SWF.c @@ -0,0 +1,803 @@ +/* SWF.c + + Python wrapper for librfxswf- module core. + + Part of the swftools package. + + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#undef HAVE_STAT +#include "../rfxswf.h" +#include "../log.h" +#include "./pyutils.h" +#include "primitives.h" +#include "action.h" + +/* +TODO: + 1) taglist is rfxswflib's linked list. It should maybe implemented as Python + list, which would, however, mean that we would have to convert the list + back and forth for the following functions: + load, save, writeCGI, unfoldAll, foldAll, optimizeOrder + 2) taglist should have an ID handler. Every time a tag is inserted, it's ID + is stored in a lookup list. + 3) +*/ + +//-------------------------- Types ------------------------------------------- + +staticforward PyTypeObject SWFClass; +staticforward PyTypeObject TagListClass; +staticforward PyTypeObject TagClass; + +/* Tags, Objects */ + +typedef struct { + PyObject_HEAD + TAG*tag; + /* ST_DEFINEFONT*/ + SWFFONT* font; + /* ST_PLACEOBJECT, ST_PLACEOBJECT2*/ + SWFPLACEOBJECT* placeobject; + PyObject* character; +} TagObject; + +typedef struct { + PyObject_HEAD + TAG*firstTag; + TAG*searchTag; + TAG*lastTag; +} TagListObject; + +typedef struct { + PyObject_HEAD + SWF swf; //swf.firstTag ist not used + TagListObject*taglist; + char*filename; +} SWFObject; + +//---------------------------------------------------------------------------- +static PyObject* f_create(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"version", "fps", "bbox", "name", NULL}; + SWFObject* swf; + int version = 6; + double framerate = 25; + PyObject * obbox = 0; + SRECT bbox = {0,0,0,0}; + char* filename = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|idOs", + kwlist, &version, &framerate, + &obbox, filename)) + return NULL; + + if (!PyArg_Parse(obbox, "(iiii)", &bbox.xmin, &bbox.ymin, &bbox.xmax, &bbox.ymax)) + return NULL; + + swf = PyObject_New(SWFObject, &SWFClass); + memset(&swf->swf, 0, sizeof(SWF)); + if(filename) + swf->filename = strdup(filename); + else + swf->filename = 0; + + swf->swf.fileVersion = version; + swf->swf.frameRate = (int)(framerate*0x100); + swf->swf.movieSize = bbox; + swf->taglist = PyObject_New(TagListObject, &TagListClass); + swf->taglist->firstTag = 0; + swf->taglist->searchTag = 0; + swf->taglist->lastTag = 0; + + if(swf->swf.fileVersion>=6) + swf->swf.compressed = 1; + + mylog("create %08x -> %08x\n", (int)self, (int)swf); + return (PyObject*)swf; +} +//---------------------------------------------------------------------------- +static PyObject* f_load(PyObject* self, PyObject* args) +{ + char* filename; + SWFObject* swf; + int fi; + + if (!PyArg_ParseTuple(args,"s:load", &filename)) + return NULL; + + swf = PyObject_New(SWFObject, &SWFClass); + memset(&swf->swf, 0, sizeof(SWF)); + swf->filename = strdup(filename); + swf->taglist = PyObject_New(TagListObject, &TagListClass); + + if(!filename) { + PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename)); + return 0; + } + fi = open(filename,O_RDONLY|O_BINARY); + if (fi<0) { + PyErr_SetString(PyExc_Exception, setError("Couldn't open file %s", filename)); + return 0; + } + if(swf_ReadSWF(fi,&swf->swf)<0) { + close(fi); + PyErr_SetString(PyExc_Exception, setError("%s is not a valid SWF file or contains errors",filename)); + return 0; + } + close(fi); + + swf->taglist->firstTag = swf->swf.firstTag; + swf->taglist->searchTag = swf->swf.firstTag; + swf->taglist->lastTag = swf->swf.firstTag; + swf->swf.firstTag = 0; + + mylog("load %08x -> %08x\n", (int)self, (int)swf); + return (PyObject*)swf; +} +//---------------------------------------------------------------------------- +static PyObject * swf_save(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"name", "compress", NULL}; + SWFObject*swfo; + SWF*swf; + int fi; + char*filename = 0; + int compress = 0; + + if(!self) + return NULL; + + swfo = (SWFObject*)self; + swf = &swfo->swf; + + filename = swfo->filename; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &filename, &compress)) + return NULL; + + // keyword arg compress (=1) forces compression + if(compress) + swf->compressed = 1; + + swf->firstTag = swfo->taglist->firstTag; + + // fix the file, in case it is empty or not terminated properly + { + TAG*tag = swf->firstTag; + if(!tag) + tag = swf->firstTag = swf_InsertTag(0,ST_END); + while(tag && tag->next) + tag = tag->next; + if(tag->id != ST_END) { + tag = swf_InsertTag(tag,ST_END); + } + } + + fi = open(filename, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); + if(fi<0) { + PyErr_SetString(PyExc_Exception, setError("couldn't create output file %s", filename)); + return 0; + } + if(swf->compressed) { + if(swf_WriteSWC(fi, swf)<0) { + close(fi); + PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed.")); + return 0; + } + } else { + if(swf_WriteSWF(fi, swf)<0) { + close(fi); + PyErr_SetString(PyExc_Exception, setError("WriteSWC() failed.")); + return 0; + } + } + close(fi); + + swf->firstTag = 0; + + return PY_NONE; +} +//---------------------------------------------------------------------------- +static PyObject * swf_writeCGI(PyObject* self, PyObject* args) +{ + SWFObject*swf = (SWFObject*)self; + if(!self || !PyArg_ParseTuple(args,"")) + return NULL; + swf->swf.firstTag = swf->taglist->firstTag; + swf_WriteCGI(&swf->swf); + swf->swf.firstTag = 0; + return PY_NONE; +} +//---------------------------------------------------------------------------- +static PyObject * taglist_foldAll(PyObject* self, PyObject* args) +{ + SWF swf; + TagListObject*taglist = (TagListObject*)self; + if(!self || !PyArg_ParseTuple(args,"")) + return NULL; + swf.firstTag = taglist->firstTag; + swf_FoldAll(&swf); + taglist->firstTag = swf.firstTag; + taglist->lastTag = 0; // FIXME + taglist->searchTag = 0; + return PY_NONE; +} +//---------------------------------------------------------------------------- +static PyObject * taglist_unfoldAll(PyObject* self, PyObject* args) +{ + SWF swf; + TagListObject*taglist = (TagListObject*)self; + if(!self || !PyArg_ParseTuple(args,"")) + return NULL; + swf.firstTag = taglist->firstTag; + swf_UnFoldAll(&swf); + taglist->firstTag = swf.firstTag; + taglist->lastTag = 0; // FIXME + taglist->searchTag = 0; + return PY_NONE; +} +//---------------------------------------------------------------------------- +static PyObject * taglist_optimizeOrder(PyObject* self, PyObject* args) +{ + SWF swf; + TagListObject*taglist = (TagListObject*)self; + if(!self || !PyArg_ParseTuple(args,"")) + return NULL; + swf.firstTag = taglist->firstTag; + swf_UnFoldAll(&swf); + taglist->firstTag = swf.firstTag; + taglist->lastTag = 0; // FIXME + taglist->searchTag = 0; + return PY_NONE; +} +//---------------------------------------------------------------------------- + +//TODO: void swf_Relocate(SWF*swf, char*bitmap); // bitmap is 65536 bytes, bitmap[a]==0 means id a is free + +static PyMethodDef swf_functions[] = +{{"save", (PyCFunction)swf_save, METH_KEYWORDS, "Save SWF to disk"}, + {"writeCGI", (PyCFunction)swf_writeCGI, METH_VARARGS, "print SWF as CGI to stdout"}, + {NULL, NULL, 0, NULL} +}; + +static PyMethodDef taglist_functions[] = +{{"foldAll", taglist_foldAll, METH_VARARGS, "fold all sprites (movieclips) in the list"}, + {"unfoldAll", taglist_unfoldAll, METH_VARARGS, "unfold (expand) all sprites (movieclips) in the list"}, + {"optimizeOrder", taglist_optimizeOrder, METH_VARARGS, "Reorder the Tag structure"}, + {NULL, NULL, 0, NULL} +}; + +//---------------------------------------------------------------------------- +static void swf_dealloc(PyObject* self) +{ + SWFObject*swfo; + SWF*swf; + swfo = (SWFObject*)self; + swf = &swfo->swf; + mylog("swf_dealloc %08x(%d)\n", (int)self, self->ob_refcnt); + if(swfo->filename) { + free(swfo->filename); + swfo->filename = 0; + } + Py_DECREF(swfo->taglist); + swfo->taglist = 0; + PyObject_Del(self); +} +//---------------------------------------------------------------------------- +static void taglist_dealloc(PyObject* self) +{ + TagListObject*taglist = (TagListObject*)self; + SWF swf; + mylog("taglist_dealloc %08x(%d)\n", (int)self, self->ob_refcnt); + swf.firstTag = taglist->firstTag; + swf_FreeTags(&swf); + taglist->firstTag = 0; + taglist->lastTag = 0; + taglist->searchTag = 0; + PyObject_Del(self); +} +//---------------------------------------------------------------------------- +static int swf_print(PyObject * self, FILE *fi, int flags) //flags&Py_PRINT_RAW +{ + SWFObject*swf = (SWFObject*)self; + swf_DumpHeader(fi, &swf->swf); + //void swf_DumpSWF(FILE * f,SWF*swf); + mylog("print %08x(%d)\n", (int)self, self->ob_refcnt); + return 0; +} +//---------------------------------------------------------------------------- +static PyObject* swf_getattr(PyObject * self, char* a) +{ + SWFObject*swf = (SWFObject*)self; + PyObject* ret; + + if(!strcmp(a, "fps")) { + double fps = swf->swf.frameRate/256.0; + mylog("swf_getattr %08x(%d) %s = %f\n", (int)self, self->ob_refcnt, a, fps); + return Py_BuildValue("d", fps); + } else if(!strcmp(a, "version")) { + int version = swf->swf.fileVersion;; + mylog("swf_getattr %08x(%d) %s = %d\n", (int)self, self->ob_refcnt, a, version); + return Py_BuildValue("i", version); + } else if(!strcmp(a, "name")) { + char*filename = swf->filename; + mylog("swf_getattr %08x(%d) %s = %s\n", (int)self, self->ob_refcnt, a, filename); + return Py_BuildValue("s", filename); + } else if(!strcmp(a, "bbox")) { + int xmin,ymin,xmax,ymax; + xmin = swf->swf.movieSize.xmin; + ymin = swf->swf.movieSize.ymin; + xmax = swf->swf.movieSize.xmax; + ymax = swf->swf.movieSize.ymax; + mylog("swf_getattr %08x(%d) %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax); + return Py_BuildValue("(iiii)", xmin, ymin, xmax, ymax); + } else if(!strcmp(a, "tags")) { + PyObject*ret = (PyObject*)(swf->taglist); + Py_INCREF(ret); + mylog("swf_getattr %08x(%d) %s = %08x(%d)\n", (int)self, self->ob_refcnt, a, ret, ret->ob_refcnt); + return ret; + } + + ret = Py_FindMethod(swf_functions, self, a); + mylog("swf_getattr %08x(%d) %s: %08x\n", (int)self, self->ob_refcnt, a, ret); + return ret; +} +//---------------------------------------------------------------------------- +static int swf_setattr(PyObject * self, char* a, PyObject * o) +{ + SWFObject*swf = (SWFObject*)self; + if(!strcmp(a, "fps")) { + double fps; + if (!PyArg_Parse(o, "d", &fps)) + goto err; + swf->swf.frameRate = (int)(fps*0x100); + mylog("swf_setattr %08x(%d) %s = %f\n", (int)self, self->ob_refcnt, a, fps); + return 0; + } else if(!strcmp(a, "version")) { + int version; + if (!PyArg_Parse(o, "i", &version)) + goto err; + swf->swf.fileVersion = version; + mylog("swf_setattr %08x(%d) %s = %d\n", (int)self, self->ob_refcnt, a, version); + return 0; + } else if(!strcmp(a, "name")) { + char*filename; + if (!PyArg_Parse(o, "s", &filename)) + goto err; + if(swf->filename) { + free(swf->filename);swf->filename=0; + } + swf->filename = strdup(filename); + mylog("swf_setattr %08x(%d) %s = %s\n", (int)self, self->ob_refcnt, a, filename); + return 0; + } else if(!strcmp(a, "bbox")) { + int xmin=0,ymin=0,xmax=0,ymax=0; + if (!PyArg_Parse(o, "(iiii)", &xmin, &ymin, &xmax, &ymax)) + goto err; + + swf->swf.movieSize.xmin = xmin; + swf->swf.movieSize.ymin = ymin; + swf->swf.movieSize.xmax = xmax; + swf->swf.movieSize.ymax = ymax; + mylog("swf_setattr %08x(%d) %s = (%d,%d,%d,%d)\n", (int)self, self->ob_refcnt, a, xmin,ymin,xmax,ymax); + return 0; + } else if(!strcmp(a, "tags")) { + TagListObject* taglist; + /*if (!PyArg_Parse(o, "O!", &TagListClass, &taglist)); + goto err;*/ + taglist = (TagListObject*)o; + Py_DECREF(swf->taglist); + swf->taglist = taglist; + Py_INCREF(swf->taglist); + mylog("swf_setattr %08x(%d) %s = %08x\n", (int)self, self->ob_refcnt, a, swf->taglist); + return 0; + } +err: + mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o); + return 1; +} + +//---------------------------------------------------------------------------- +static PyObject* taglist_getattr(PyObject * self, char* a) +{ + PyObject* ret = Py_FindMethod(taglist_functions, self, a); + mylog("taglist_getattr %08x(%d) %s: %08x\n", (int)self, self->ob_refcnt, a, ret); + return ret; +} +//---------------------------------------------------------------------------- +static int taglist_length(PyObject * self) +{ + TagListObject*tags = (TagListObject*)self; + TAG*tag; + int l = 0; + mylog("taglist_length %08x(%d)", (int)self, self->ob_refcnt); + tag = tags->firstTag; + while(tag) { + l++; + tag = tag->next; + } + return l; +} +//---------------------------------------------------------------------------- +static PyObject * taglist_concat(PyObject * self, PyObject* list) +{ + TagObject*tag; + TagListObject*taglist = (TagListObject*)self; + mylog("taglist_concat %08x(%d)", (int)self, self->ob_refcnt); + + if (PyArg_Parse(list, "O!", &TagClass, &tag)) { + /* copy tag, so we don't have to do INCREF(tag) (and don't + get problems if the tag is appended to more than one + taglist) */ + /* TODO: handle IDs */ + mylog("taglist_concat: Tag", (int)self, self->ob_refcnt); + taglist->lastTag = swf_InsertTag(taglist->lastTag, tag->tag->id); + swf_SetBlock(taglist->lastTag, tag->tag->data, tag->tag->len); + if(!taglist->firstTag) { + taglist->firstTag = taglist->searchTag = taglist->lastTag; + } + Py_INCREF(self); + return self; + } + PyErr_Clear(); + if (PyList_Check(list)) { + mylog("taglist_concat: PythonList", (int)self, self->ob_refcnt); + Py_INCREF(self); + return self; + } + return 0; +} +//---------------------------------------------------------------------------- +static int taglist_contains(PyObject * self, PyObject* other) +{ + mylog("taglist_contains %08x(%d)", (int)self, self->ob_refcnt); + return 0; +} +//---------------------------------------------------------------------------- +staticforward TagObject* TagObject_New(); +static PyObject * taglist_item(PyObject * self, int index) +{ + TagListObject*taglist = (TagListObject*)self; + TAG*tag; + TagObject*tagobject; + int i = 0; + mylog("taglist_item %08x(%d) [%d]", (int)self, self->ob_refcnt, i); + + if(i<0) { + PyErr_SetString(PyExc_Exception, setError("Negative Indices not supported.")); + return NULL; + } + + tag = taglist->firstTag; + while(tag && inext; + } + if(!tag || i != index) { + PyErr_SetString(PyExc_Exception, setError("No Tag at position %d", index)); + return NULL; + } + + tagobject = TagObject_New(); + tagobject->tag = tag; + + return (PyObject*)tagobject; +} +//---------------------------------------------------------------------------- +static void tag_dealloc(PyObject * self) +{ + TagObject*tag = (TagObject*)self; + mylog("tag_dealoc %08x(%d)\n", (int)self, self->ob_refcnt); + if(tag->placeobject) { + swf_PlaceObjectFree(tag->placeobject); + tag->placeobject = 0; + } + if(tag->font) { + swf_FontFree(tag->font); + tag->font = 0; + } + if(tag->character) { + Py_DECREF(tag->character); + tag->character = 0; + } + PyObject_Del(self); +} +//---------------------------------------------------------------------------- +static PyObject* tag_setU8(PyObject * self, PyObject*other) +{ + return NULL; +} +//---------------------------------------------------------------------------- +static PyObject* tag_setbackgroundcolor_getrgb(PyObject * self, PyObject*other) +{ + TagObject*tag = (TagObject*)self; + int r,g,b; + r = tag->tag->data[0]; + g = tag->tag->data[1]; + b = tag->tag->data[2]; + return Py_BuildValue("(iii)", r,g,b); +} +//---------------------------------------------------------------------------- + +static struct tagfunctions { + int id; + PyMethodDef f[8]; +} tagfunctions[] = +{ + { + ST_SETBACKGROUNDCOLOR, + {{"getRGB", tag_setbackgroundcolor_getrgb, METH_VARARGS, "get's the color set by this tag"}, + {NULL, NULL, 0, NULL} + } + } +}; +static PyMethodDef common_tagfunctions[] = +{{"setU8", tag_setU8, METH_VARARGS, "sets a byte to the tag data"}, + {NULL, NULL, 0, NULL} +}; + +static PyObject* tag_getattr(PyObject * self, char* a) +{ + TagObject*tag = (TagObject*)self; + PyObject* ret = NULL; + int id = tag->tag->id; + int t; + + /* search for a tag specific function */ + for(t=0;tob_refcnt, a, ret); + return ret; +} +//---------------------------------------------------------------------------- +// Tag Contructors +//---------------------------------------------------------------------------- +static TagObject* TagObject_New() +{ + TagObject*tag = PyObject_New(TagObject, &TagClass); + tag->font = 0; + tag->character = 0; + tag->placeobject = 0; + tag->tag = 0; + return tag; +} + +static PyObject* f_SetBackgroundColor(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"color", NULL}; + int r=0,g=0,b=0; + TagObject*tag; + ColorObject*color; + + /* 1st try- copy constructor */ + if(!PyArg_ParseTupleAndKeywords(args, kwargs, "O!", kwlist, &ColorClass, &color)) { + /* 2nd try- color's contructor */ + color = (ColorObject*)f_Color(NULL, args, kwargs); + } + if(!color) + return NULL; + + tag = TagObject_New(); + tag->tag = swf_InsertTag(0, ST_SETBACKGROUNDCOLOR); + swf_SetU8(tag->tag, color->rgba.r); + swf_SetU8(tag->tag, color->rgba.g); + swf_SetU8(tag->tag, color->rgba.b); + mylog("SetBackgroundColor(%02x,%02x,%02x) %08x -> %08x\n", color->rgba.r, color->rgba.g, color->rgba.b, (int)self, tag); + return (PyObject*)tag; +} +//---------------------------------------------------------------------------- +static PyObject* f_DefineFont(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"filename", NULL}; + char*filename = 0; + TagObject*tag; + SWFFONT* font; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &filename)) + return NULL; + + font = swf_ReadFont(filename); + mylog("font=%08x",font); + if(!font) { + PyErr_SetString(PyExc_Exception, setError("Could not load %s", filename)); + return NULL; + } + + tag = TagObject_New(); + tag->font = font; + tag->tag = swf_InsertTag(0, ST_DEFINEFONT2); + tag->font->id = 0xabcd; // swf_SetU16(id); + swf_FontSetDefine2(tag->tag, tag->font); // TODO: should this be done later, in taglist? + mylog("DefineFont %08x -> %08x\n", (int)self, (int)tag); + return (PyObject*)tag; +} +//---------------------------------------------------------------------------- +static PyObject* f_DefineText(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"font", "text", "size", "color", NULL}; + TagObject*tag; + char*text = 0; + int textlen = 0; + PyObject*unicode16; + PyObject*unicode8; + int size = 0; + RGBA rgba = {0,0,0,255}; + ColorObject*color = 0; + TagObject*font = 0; + SRECT r; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!u#i|O!", kwlist, &TagClass, &font, &text, &textlen, &size, &ColorClass, &color)) + return NULL; + + unicode16 = PyUnicode_DecodeUTF16(text, textlen*2, NULL, NULL); + unicode8 = PyUnicode_AsUTF8String(unicode16); + text = PyString_AS_STRING(unicode8); + + if(color) + rgba = color->rgba; + + mylog("DefineText: text = %s", text); + + tag = TagObject_New(); + tag ->tag= swf_InsertTag(0, ST_DEFINETEXT2); + swf_SetU16(tag->tag, /*ID*/0); + r = swf_SetDefineText(tag->tag, font->font, &rgba, text, size); + mylog("DefineText %08x -> %08x\n", (int)self, (int)tag); + return (PyObject*)tag; +} +//---------------------------------------------------------------------------- +static PyObject* f_PlaceObject(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"character", "depth", "matrix", "colortransform", "ratio", "name", "clipdepth", "action"}; + TagObject*tag; + + TagObject*character = 0; + int depth; + int clipdepth = 0; + MatrixObject*matrix = 0; + CXFormObject*cxform = 0; + int ratio = 0; + ActionObject*action = 0; + char* name = 0; + SWFPLACEOBJECT* po; + po = malloc(sizeof(SWFPLACEOBJECT)); + memset(po, 0, sizeof(SWFPLACEOBJECT)); + + swf_GetPlaceObject(0, po); + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!i|O!O!isiO!", kwlist, + &TagClass, &character, + &depth, + &MatrixClass, &matrix, + &CXFormClass, &cxform, + &ratio, + &name, + &clipdepth, + &action + )) + return NULL; + po->depth = depth; + po->id = /*ID*/ 0; + po->clipdepth = clipdepth; + po->ratio = ratio; + po->name = name; + if(clipdepth) po->matrix = matrix->matrix; + if(cxform) po->cxform = cxform->cxform; + if(action) po->actions = action->action; + + tag = TagObject_New(); + tag->placeobject = po; + Py_INCREF(character); + tag->character = (PyObject*)character; + tag->tag= swf_InsertTag(0, ST_PLACEOBJECT2); + swf_SetPlaceObject(tag->tag, po); + mylog("PlaceObject %08x -> %08x\n", (int)self, (int)tag); + return (PyObject*)tag; +} +//---------------------------------------------------------------------------- +static PyTypeObject SWFClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "SWF", + tp_basicsize: sizeof(SWFObject), + tp_itemsize: 0, + tp_dealloc: swf_dealloc, + tp_print: swf_print, + tp_getattr: swf_getattr, + tp_setattr: swf_setattr, +}; +static PySequenceMethods taglist_as_sequence = +{ + sq_length: taglist_length, // len(obj) + sq_concat: taglist_concat, // obj += [...], obj1+obj2 + sq_repeat: 0, // x*n, intargfunc + sq_item: taglist_item, // obj[3] + sq_slice: 0, // x[i:j] intintargfunc + sq_ass_item: 0, // x[i] = y intobjargproc + sq_ass_slice: 0, // x[i:j] = v intintobjargproc + sq_contains: taglist_contains, //??? +}; +static PyTypeObject TagListClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "TagList", + tp_basicsize: sizeof(TagListObject), + tp_itemsize: 0, + tp_dealloc: taglist_dealloc, + tp_print: 0, // print x + tp_getattr: taglist_getattr, // x.attr + tp_setattr: 0, // x.attr = v + tp_compare: 0, // x>y + tp_repr: 0, // `x`, print x + tp_as_number: 0, + tp_as_sequence: &taglist_as_sequence, +}; +static PyTypeObject TagClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "Tag", + tp_basicsize: sizeof(TagObject), + tp_itemsize: 0, + tp_dealloc: tag_dealloc, + tp_print: 0, + tp_getattr: tag_getattr, +}; +//---------------------------------------------------------------------------- + +static PyMethodDef SWFMethods[] = +{ + /* SWF creation*/ + {"load", f_load, METH_VARARGS, "Load a SWF from disc."}, + {"create", (PyCFunction)f_create, METH_KEYWORDS, "Create a new SWF from scratch."}, + + /* Primitives */ + {"Color", (PyCFunction)f_Color, METH_KEYWORDS, "Create a new color object."}, + {"Gradient", (PyCFunction)f_Gradient, METH_KEYWORDS, "Create a new gradient object."}, + {"ColorTransform", (PyCFunction)f_ColorTransform, METH_KEYWORDS, "Create a new colortransform object."}, + {"Matrix", (PyCFunction)f_Matrix, METH_KEYWORDS, "Create a new matrix object."}, + {"BBox", (PyCFunction)f_BBox, METH_KEYWORDS, "Create a new bounding box object."}, + + /* TAGS */ + {"SetBackgroundColor", (PyCFunction)f_SetBackgroundColor, METH_KEYWORDS, "Create a SetBackGroundColor Tag."}, + {"DefineFont", (PyCFunction)f_DefineFont, METH_KEYWORDS, "Create a DefineFont Tag."}, + {"DefineText", (PyCFunction)f_DefineText, METH_KEYWORDS, "Create a DefineText Tag."}, + {"PlaceObject", (PyCFunction)f_PlaceObject, METH_KEYWORDS, "Create a PlaceObject Tag."}, + {NULL, NULL, 0, NULL} +}; + +void initSWF(void) +{ + SWFClass.ob_type = &PyType_Type; + + initLog("test.log",8,0,0,0,0); + + (void)Py_InitModule("SWF", SWFMethods); +} diff --git a/lib/python/action.c b/lib/python/action.c new file mode 100644 index 0000000..388087e --- /dev/null +++ b/lib/python/action.c @@ -0,0 +1,90 @@ +/* action.c + + Python wrapper for librfxswf- actionscript stuff + + Part of the swftools package. + + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#undef HAVE_STAT +#include "../rfxswf.h" +#include "../log.h" +#include "./pyutils.h" +#include "action.h" + +PyObject* f_Action(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"r", "g", "b", "a", NULL}; + ActionObject* action; + int r=0,g=0,b=0,a=255; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii|i", kwlist, &r,&g,&b,&a)) + return NULL; + action = PyObject_New(ActionObject, &ActionClass); + action->rgba.r = r; + action->rgba.g = g; + action->rgba.b = b; + action->rgba.a = a; + return (PyObject*)action; +} +static PyObject* action_getattr(PyObject * self, char* a) +{ + ActionObject*action = (ActionObject*)self; + if(!strcmp(a, "r")) { + return Py_BuildValue("r", action->rgba.r); + } else if(!strcmp(a, "g")) { + return Py_BuildValue("g", action->rgba.g); + } else if(!strcmp(a, "b")) { + return Py_BuildValue("b", action->rgba.b); + } else if(!strcmp(a, "a")) { + return Py_BuildValue("a", action->rgba.a); + } + return NULL; +} +static int action_setattr(PyObject * self, char* attr, PyObject* o) +{ + ActionObject*action = (ActionObject*)self; + if(!strcmp(attr, "r")) { + if (!PyArg_Parse(o, "d", &action->rgba.r)) goto err; + return 0; + } else if(!strcmp(attr, "g")) { + if (!PyArg_Parse(o, "d", &action->rgba.g)) goto err; + return 0; + } else if(!strcmp(attr, "b")) { + if (!PyArg_Parse(o, "d", &action->rgba.b)) goto err; + return 0; + } else if(!strcmp(attr, "a")) { + if (!PyArg_Parse(o, "d", &action->rgba.a)) goto err; + return 0; + } +err: + mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, attr, o); + return 1; +} + +PyTypeObject ActionClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "Action", + tp_basicsize: sizeof(ActionObject), + tp_itemsize: 0, + tp_dealloc: dummy_dealloc, + tp_print: 0, + tp_getattr: action_getattr, + tp_setattr: action_setattr, +}; diff --git a/lib/python/action.h b/lib/python/action.h new file mode 100644 index 0000000..e77dfac --- /dev/null +++ b/lib/python/action.h @@ -0,0 +1,38 @@ +/* action.c + + Python wrapper for librfxswf- actionscript stuff (header) + + Part of the swftools package. + + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef __action_h__ +#define __action_h__ + +#include "../rfxswf.h" +#undef HAVE_STAT +#include + +extern PyTypeObject ActionClass; + +typedef struct { + PyObject_HEAD + ActionTAG*action; +} ActionObject; + +PyObject* f_Action(PyObject* self, PyObject* args, PyObject* kwargs); +#endif diff --git a/lib/python/mypython.c b/lib/python/mypython.c new file mode 100644 index 0000000..eacd669 --- /dev/null +++ b/lib/python/mypython.c @@ -0,0 +1,5 @@ +#include +int main(int argn, char*argv[]) +{ + return Py_Main(argn, argv); +} diff --git a/lib/python/primitives.c b/lib/python/primitives.c new file mode 100644 index 0000000..f3bc3d2 --- /dev/null +++ b/lib/python/primitives.c @@ -0,0 +1,236 @@ +/* primitives.c + + Python wrapper for librfxswf- primitive objects (implementation) + + Part of the swftools package. + + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#undef HAVE_STAT +#include "../rfxswf.h" +#include "../log.h" +#include "./pyutils.h" +#include "primitives.h" + +PyObject* f_Color(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"r", "g", "b", "a", NULL}; + ColorObject* color; + int r=0,g=0,b=0,a=255; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iii|i", kwlist, &r,&g,&b,&a)) + return NULL; + color = PyObject_New(ColorObject, &ColorClass); + color->rgba.r = r; + color->rgba.g = g; + color->rgba.b = b; + color->rgba.a = a; + return (PyObject*)color; +} +static PyObject* color_getattr(PyObject * self, char* a) +{ + ColorObject*color = (ColorObject*)self; + if(!strcmp(a, "r")) { + return Py_BuildValue("r", color->rgba.r); + } else if(!strcmp(a, "g")) { + return Py_BuildValue("g", color->rgba.g); + } else if(!strcmp(a, "b")) { + return Py_BuildValue("b", color->rgba.b); + } else if(!strcmp(a, "a")) { + return Py_BuildValue("a", color->rgba.a); + } + return NULL; +} +static int color_setattr(PyObject * self, char* attr, PyObject* o) +{ + ColorObject*color = (ColorObject*)self; + if(!strcmp(attr, "r")) { + if (!PyArg_Parse(o, "d", &color->rgba.r)) goto err; + return 0; + } else if(!strcmp(attr, "g")) { + if (!PyArg_Parse(o, "d", &color->rgba.g)) goto err; + return 0; + } else if(!strcmp(attr, "b")) { + if (!PyArg_Parse(o, "d", &color->rgba.b)) goto err; + return 0; + } else if(!strcmp(attr, "a")) { + if (!PyArg_Parse(o, "d", &color->rgba.a)) goto err; + return 0; + } +err: + mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, attr, o); + return 1; +} +//---------------------------------------------------------------------------- +PyObject* f_BBox(PyObject* self, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {"xmin", "ymin", "xmax", "ymax", NULL}; + BBoxObject* bbox; + SRECT box; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii", kwlist, + &box.xmin, + &box.ymin, + &box.xmax, + &box.ymax)); + return NULL; + bbox = PyObject_New(BBoxObject, &BBoxClass); + bbox->bbox = box; + return (PyObject*)bbox; +} +static PyObject* bbox_getattr(PyObject * self, char* a) +{ + BBoxObject*bbox = (BBoxObject*)self; + if(!strcmp(a, "xmin")) { + return Py_BuildValue("i", bbox->bbox.xmin); + } else if(!strcmp(a, "ymin")) { + return Py_BuildValue("i", bbox->bbox.ymin); + } else if(!strcmp(a, "xmax")) { + return Py_BuildValue("i", bbox->bbox.xmax); + } else if(!strcmp(a, "ymax")) { + return Py_BuildValue("i", bbox->bbox.ymax); + } + return NULL; +} +static int bbox_setattr(PyObject * self, char* a, PyObject* o) +{ + BBoxObject*bbox= (BBoxObject*)self; + if(!strcmp(a, "xmin")) { + if (!PyArg_Parse(o, "i", &bbox->bbox.xmin)) goto err; + return 0; + } else if(!strcmp(a, "ymin")) { + if (!PyArg_Parse(o, "i", &bbox->bbox.ymin)) goto err; + return 0; + } else if(!strcmp(a, "xmax")) { + if (!PyArg_Parse(o, "i", &bbox->bbox.xmax)) goto err; + return 0; + } else if(!strcmp(a, "ymax")) { + if (!PyArg_Parse(o, "i", &bbox->bbox.ymax)) goto err; + return 0; + } +err: + mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o); + return 1; +} +//---------------------------------------------------------------------------- +PyObject* f_Matrix(PyObject* self, PyObject* args, PyObject* kwargs) +{ + return NULL; +} +static PyObject* matrix_getattr(PyObject * self, char* a) +{ + return NULL; +} +static int matrix_setattr(PyObject * self, char* a, PyObject* o) +{ + return 0; +} +//---------------------------------------------------------------------------- +PyObject* f_ColorTransform(PyObject* self, PyObject* args, PyObject* kwargs) +{ + return NULL; +} +static PyObject* colortransform_getattr(PyObject * self, char* a) +{ + return NULL; +} +static int colortransform_setattr(PyObject * self, char* a, PyObject* o) +{ + return 0; +} +//---------------------------------------------------------------------------- +PyObject* f_Gradient(PyObject* self, PyObject* args, PyObject* kwargs) +{ + return NULL; +} +static PyObject* gradient_getattr(PyObject * self, char* a) +{ + return NULL; +} +static int gradient_setattr(PyObject * self, char* a, PyObject* o) +{ + return 0; +} +//---------------------------------------------------------------------------- + +PyTypeObject ColorClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "Color", + tp_basicsize: sizeof(ColorObject), + tp_itemsize: 0, + tp_dealloc: dummy_dealloc, + tp_print: 0, + tp_getattr: color_getattr, + tp_setattr: color_setattr, +}; +PyTypeObject BBoxClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "BBox", + tp_basicsize: sizeof(BBoxObject), + tp_itemsize: 0, + tp_dealloc: dummy_dealloc, + tp_print: 0, + tp_getattr: bbox_getattr, + tp_setattr: bbox_setattr, +}; +PyTypeObject GradientClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "Gradient", + tp_basicsize: sizeof(GradientObject), + tp_itemsize: 0, + tp_dealloc: dummy_dealloc, + tp_print: 0, + tp_getattr: gradient_getattr, + tp_setattr: gradient_setattr, +}; +PyTypeObject CXFormClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "ColorTransform", + tp_basicsize: sizeof(CXFormObject), + tp_itemsize: 0, + tp_dealloc: dummy_dealloc, + tp_print: 0, + tp_getattr: colortransform_getattr, + tp_setattr: colortransform_setattr, +}; +PyTypeObject MatrixClass = +{ + PyObject_HEAD_INIT(NULL) + 0, + tp_name: "Matrix", + tp_basicsize: sizeof(MatrixObject), + tp_itemsize: 0, + tp_dealloc: dummy_dealloc, + tp_print: 0, + tp_getattr: matrix_getattr, + tp_setattr: matrix_setattr, + tp_compare: 0, + tp_repr: 0, + tp_as_number: 0, + tp_as_sequence: 0, + tp_as_mapping: 0, + tp_hash: 0, // dict(x) + tp_call: 0, // x() + tp_str: 0 // str(x) +}; diff --git a/lib/python/primitives.h b/lib/python/primitives.h new file mode 100644 index 0000000..09d695c --- /dev/null +++ b/lib/python/primitives.h @@ -0,0 +1,65 @@ +/* primitives.h + + Python wrapper for librfxswf- primitive objects (structs, prototypes) + + Part of the swftools package. + + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef __primitives_h__ +#define __primitives_h__ + +#undef HAVE_STAT +#include + +extern PyTypeObject ColorClass; +extern PyTypeObject BBoxClass; +extern PyTypeObject CXFormClass; +extern PyTypeObject GradientClass; +extern PyTypeObject MatrixClass; + +typedef struct { + PyObject_HEAD + RGBA rgba; +} ColorObject; + +typedef struct { + PyObject_HEAD + SRECT bbox; +} BBoxObject; + +typedef struct { + PyObject_HEAD + MATRIX matrix; +} MatrixObject; + +typedef struct { + PyObject_HEAD + CXFORM cxform; +} CXFormObject; + +typedef struct { + PyObject_HEAD + GRADIENT gradient; +} GradientObject; + +PyObject* f_Color(PyObject* self, PyObject* args, PyObject* kwargs); +PyObject* f_ColorTransform(PyObject* self, PyObject* args, PyObject* kwargs); +PyObject* f_Gradient(PyObject* self, PyObject* args, PyObject* kwargs); +PyObject* f_BBox(PyObject* self, PyObject* args, PyObject* kwargs); +PyObject* f_Matrix(PyObject* self, PyObject* args, PyObject* kwargs); +#endif diff --git a/lib/python/pyutils.c b/lib/python/pyutils.c new file mode 100644 index 0000000..2fdc0e1 --- /dev/null +++ b/lib/python/pyutils.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +char* setError(char*format, ...) +{ + char buf[1024]; + int l; + va_list arglist; + va_start(arglist, format); + vsprintf(buf, format, arglist); + va_end(arglist); + l = strlen(buf); + while(l && buf[l-1]=='\n') { + buf[l-1] = 0; + l--; + } + return strdup(buf); +} + +static int verbose = 1; +void mylog(char*format, ...) +{ + char buf[1024]; + int l; + va_list arglist; + if(!verbose) + return; + va_start(arglist, format); + vsprintf(buf, format, arglist); + va_end(arglist); + l = strlen(buf); + while(l && buf[l-1]=='\n') { + buf[l-1] = 0; + l--; + } + fprintf(stderr, "[SWF] %s\n", buf); + fflush(stderr); +} + +#define PY_NONE Py_BuildValue("s", 0) + +PyObject* FindMethodMore(PyObject*ret, PyMethodDef f[], PyObject*self, char* a) +{ + if(ret==NULL) { + ret = Py_FindMethod(f, self, a); + } else { + if(!strcmp(a, "__methods__")) { + /* we are being dir()ed. Complete the function table */ + PyObject* add = Py_FindMethod(f, self, a); + int t; + mylog("taglist_getattr: append common funtions %08x %08x\n", ret, add); + for(t=0;t + +#define PY_NONE Py_BuildValue("s", 0) + +char* setError(char*format, ...); +void mylog(char*format, ...); +PyObject* FindMethodMore(PyObject*ret, PyMethodDef f[], PyObject*self, char* a); +void dummy_dealloc(PyObject* self); +#endif -- 1.7.10.4