added f_Matrix2()
[swftools.git] / lib / python / primitives.c
index f3bc3d2..cbd2442 100644 (file)
 #include "./pyutils.h"
 #include "primitives.h"
 
-PyObject* f_Color(PyObject* self, PyObject* args, PyObject* kwargs)
+//----------------------------------------------------------------------------
+typedef struct {
+    PyObject_HEAD
+    RGBA rgba;
+} ColorObject;
+
+PyObject* f_Color2(U8 r, U8 g, U8 b, U8 a)
 {
-    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);
+    ColorObject* color = PyObject_New(ColorObject, &ColorClass);
     color->rgba.r = r;
     color->rgba.g = g;
     color->rgba.b = b;
     color->rgba.a = a;
     return (PyObject*)color;
 }
+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)) {
+       char*s= 0;
+       int mya = -1;
+       PyErr_Clear();
+       static char *kwlist[] = {"col", "alpha", NULL};
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i", kwlist, &s, &mya))
+           return NULL;
+       if(mya>=0) a=mya;
+       sscanf(s, "%02x%02x%02x%02x",&r,&g,&b,&a);
+    }
+    color = PyObject_New(ColorObject, &ColorClass);
+    mylog("+%08x(%d) color_new(%d,%d,%d,%d)\n", (int)color, color->ob_refcnt, r,g,b,a);
+    return f_Color2(r,g,b,a);
+}
 static PyObject* color_getattr(PyObject * self, char* a)
 {
     ColorObject*color = (ColorObject*)self;
     if(!strcmp(a, "r")) {
-       return Py_BuildValue("r", color->rgba.r);
+       return Py_BuildValue("i", color->rgba.r);
     } else if(!strcmp(a, "g")) {
-       return Py_BuildValue("g", color->rgba.g);
+       return Py_BuildValue("i", color->rgba.g);
     } else if(!strcmp(a, "b")) {
-       return Py_BuildValue("b", color->rgba.b);
+       return Py_BuildValue("i", color->rgba.b);
     } else if(!strcmp(a, "a")) {
-       return Py_BuildValue("a", color->rgba.a);
+       return Py_BuildValue("i", color->rgba.a);
+    } else if(!strcmp(a, "alpha")) {
+       return Py_BuildValue("i", color->rgba.a);
+    } else if(!strcmp(a, "rgb")) {
+       char text[80];
+       sprintf(text, "%02x%02x%02x", color->rgba.r, color->rgba.g, color->rgba.b);
+       return PyString_FromString(text);
+    } else if(!strcmp(a, "rgba")) {
+       char text[80];
+       sprintf(text, "%02x%02x%02x%02x", color->rgba.r, color->rgba.g, color->rgba.b, color->rgba.a);
+       return PyString_FromString(text);
     }
-    return NULL;
+    return PY_ERROR("bad attribute");
 }
 static int color_setattr(PyObject * self, char* attr, PyObject* o)
 {
@@ -75,18 +105,67 @@ err:
     mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, attr, o);
     return 1;
 }
+RGBA color_getRGBA(PyObject*self)
+{
+    ColorObject*color = 0;
+    if (!PyArg_Parse(self, "O!", &ColorClass, &color)) {
+       RGBA dummy;
+       memset(&dummy, 0, sizeof(dummy));
+       mylog("Error: wrong type for function color_getRGBA");
+       return dummy;
+    }
+    return color->rgba;
+}
+void color_dealloc(PyObject* self)
+{
+    mylog("-%08x(%d) color_dealloc\n", (int)self, self->ob_refcnt);
+    PyObject_Del(self);
+}
+PyTypeObject ColorClass = 
+{
+    PyObject_HEAD_INIT(NULL)
+    0,
+    tp_name: "Color",
+    tp_basicsize: sizeof(ColorObject),
+    tp_itemsize: 0,
+    tp_dealloc: color_dealloc,
+    tp_print: 0,
+    tp_getattr: color_getattr,
+    tp_setattr: color_setattr,
+};
 //----------------------------------------------------------------------------
+typedef struct {
+    PyObject_HEAD
+    SRECT bbox;
+} BBoxObject;
+//void swf_ExpandRect(SRECT*src, SPOINT add);
+//void swf_ExpandRect2(SRECT*src, SRECT*add);
+
 PyObject* f_BBox(PyObject* self, PyObject* args, PyObject* kwargs)
 {
     static char *kwlist[] = {"xmin", "ymin", "xmax", "ymax", NULL};
     BBoxObject* bbox;
+    float xmin,ymin,xmax,ymax;
+    if(!kwargs) {
+       if (!PyArg_ParseTuple(args, "ffff", &xmin, &ymin, &xmax, &ymax))
+           return NULL;
+    } else {
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ffff", kwlist, &xmin, &ymin, &xmax, &ymax))
+           return NULL;
+    }
     SRECT box;
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iiii", kwlist, 
-               &box.xmin,
-               &box.ymin,
-               &box.xmax,
-               &box.ymax));
-       return NULL;
+    box.xmin = (int)(xmin*20);
+    box.ymin = (int)(ymin*20);
+    box.xmax = (int)(xmax*20);
+    box.ymax = (int)(ymax*20);
+    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);
+    bbox = PyObject_New(BBoxObject, &BBoxClass);
+    bbox->bbox = box;
+    return (PyObject*)bbox;
+}
+PyObject* f_BBox2(SRECT box)
+{
+    BBoxObject* bbox;
     bbox = PyObject_New(BBoxObject, &BBoxClass);
     bbox->bbox = box;
     return (PyObject*)bbox;
@@ -95,13 +174,13 @@ static PyObject* bbox_getattr(PyObject * self, char* a)
 {
     BBoxObject*bbox = (BBoxObject*)self;
     if(!strcmp(a, "xmin")) {
-       return Py_BuildValue("i", bbox->bbox.xmin);
+       return Py_BuildValue("f", bbox->bbox.xmin/20.0);
     } else if(!strcmp(a, "ymin")) {
-       return Py_BuildValue("i", bbox->bbox.ymin);
+       return Py_BuildValue("f", bbox->bbox.ymin/20.0);
     } else if(!strcmp(a, "xmax")) {
-       return Py_BuildValue("i", bbox->bbox.xmax);
+       return Py_BuildValue("f", bbox->bbox.xmax/20.0);
     } else if(!strcmp(a, "ymax")) {
-       return Py_BuildValue("i", bbox->bbox.ymax);
+       return Py_BuildValue("f", bbox->bbox.ymax/20.0);
     }
     return NULL;
 }
@@ -109,36 +188,159 @@ 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;
+       float xmin;
+       if (!PyArg_Parse(o, "f", &xmin)) goto err;
+       bbox->bbox.xmin = (int)(xmin*20);
        return 0;
     } else if(!strcmp(a, "ymin")) {
-       if (!PyArg_Parse(o, "i", &bbox->bbox.ymin)) goto err;
+       float ymin;
+       if (!PyArg_Parse(o, "f", &ymin)) goto err;
+       bbox->bbox.ymin = (int)(ymin*20);
        return 0;
     } else if(!strcmp(a, "xmax")) {
-       if (!PyArg_Parse(o, "i", &bbox->bbox.xmax)) goto err;
+       float xmax;
+       if (!PyArg_Parse(o, "f", &xmax)) goto err;
+       bbox->bbox.xmax = (int)(xmax*20);
        return 0;
     } else if(!strcmp(a, "ymax")) {
-       if (!PyArg_Parse(o, "i", &bbox->bbox.ymax)) goto err;
+       float ymax;
+       if (!PyArg_Parse(o, "f", &ymax)) goto err;
+       bbox->bbox.ymax = (int)(ymax*20);
        return 0;
     } 
 err:
     mylog("swf_setattr %08x(%d) %s = ? (%08x)\n", (int)self, self->ob_refcnt, a, o);
     return 1;
 }
+void bbox_dealloc(PyObject* self)
+{
+    mylog("-%08x(%d) bbox_dealloc\n", (int)self, self->ob_refcnt);
+    PyObject_Del(self);
+}
+SRECT bbox_getSRECT(PyObject*self)
+{
+    BBoxObject*bbox= 0;
+    if (!PyArg_Parse(self, "O!", &BBoxClass, &bbox)) {
+       SRECT dummy;
+       memset(&dummy, 0, sizeof(dummy));
+       mylog("Error: wrong type for function color_getRGBA");
+       return dummy;
+    }
+    return bbox->bbox;
+}
+PyTypeObject BBoxClass = 
+{
+    PyObject_HEAD_INIT(NULL)
+    0,
+    tp_name: "BBox",
+    tp_basicsize: sizeof(BBoxObject),
+    tp_itemsize: 0,
+    tp_dealloc: bbox_dealloc,
+    tp_print: 0,
+    tp_getattr: bbox_getattr,
+    tp_setattr: bbox_setattr,
+};
+SRECT bbox_getBBox(PyObject*self);
 //----------------------------------------------------------------------------
-PyObject* f_Matrix(PyObject* self, PyObject* args, PyObject* kwargs)
+typedef struct {
+    PyObject_HEAD
+    MATRIX matrix;
+} MatrixObject;
+
+PyObject* f_Matrix2(MATRIX* m)
 {
-    return NULL;
+    PyObject*self = (PyObject*)PyObject_New(MatrixObject, &MatrixClass);
+    MatrixObject*matrix = (MatrixObject*)self;
+    matrix->matrix = *m;
+    return self;
+}
+
+PyObject* f_Matrix(PyObject* _self, PyObject* args, PyObject* kwargs)
+{
+    PyObject*self = (PyObject*)PyObject_New(MatrixObject, &MatrixClass);
+    MatrixObject*matrix = (MatrixObject*)self;
+    mylog("+%08x(%d) f_Matrix", self, self->ob_refcnt);
+    static char *kwlist[] = {"x", "y", "scale", "rotate", "pivotx", "pivoty", NULL};
+    float x=0,y=0,scale=1.0,rotate=0,pivotx=0,pivoty=0;
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ffffff", kwlist, &x,&y,&scale,&rotate,&pivotx,&pivoty))
+       return NULL;
+    mylog(" %08x(%d) f_Matrix: x=%f y=%f scale=%f rotate=%f", self, self->ob_refcnt, x,y,scale,rotate);
+    swf_GetMatrix(0, &matrix->matrix);
+
+    matrix->matrix.tx = (int)(x*20);
+    matrix->matrix.ty = (int)(y*20);
+
+    if(!rotate) {
+       matrix->matrix.sx = (int)(scale*65536);
+       matrix->matrix.sy = (int)(scale*65536);
+    } else {
+       matrix->matrix.sx = (int)(scale*cos(rotate)*65536);
+       matrix->matrix.sy = (int)(scale*cos(rotate)*65536);
+       matrix->matrix.r0 = (int)(scale*sin(rotate)*65536);
+       matrix->matrix.r1 = (int)(-scale*sin(rotate)*65536);
+    }
+    if(pivotx || pivoty) {
+       SPOINT p,d;
+       p.x = (int)(pivotx*20);
+       p.y = (int)(pivoty*20);
+       p = swf_TurnPoint(p, &matrix->matrix);
+       matrix->matrix.tx += matrix->matrix.tx-p.x;
+       matrix->matrix.ty += matrix->matrix.ty-p.y;
+    }
+
+    /* TODO: rotate */
+    return self;
 }
 static PyObject* matrix_getattr(PyObject * self, char* a)
 {
+    PY_ASSERT_TYPE(self,&MatrixClass);
     return NULL;
 }
 static int matrix_setattr(PyObject * self, char* a, PyObject* o)
 {
+    PY_ASSERT_TYPE(self,&MatrixClass);
     return 0;
 }
+MATRIX matrix_getMatrix(PyObject*self)
+{
+    mylog(" %08x(%d) matrix_getMatrix", self, self->ob_refcnt);
+    PY_ASSERT_TYPE(self,&MatrixClass);
+    MatrixObject*matrix = (MatrixObject*)self;
+    return matrix->matrix;
+}
+void matrix_dealloc(PyObject* self)
+{
+    mylog("-%08x(%d) matrix_dealloc", self, self->ob_refcnt);
+    PyObject_Del(self);
+}
+//SPOINT swf_TurnPoint(SPOINT p, MATRIX* m);
+//SRECT swf_TurnRect(SRECT r, MATRIX* m);
+PyTypeObject MatrixClass = 
+{
+    PyObject_HEAD_INIT(NULL)
+    0,
+    tp_name: "Matrix",
+    tp_basicsize: sizeof(MatrixObject),
+    tp_itemsize: 0,
+    tp_dealloc: matrix_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)
+};
 //----------------------------------------------------------------------------
+typedef struct {
+    PyObject_HEAD
+    CXFORM cxform;
+} CXFormObject;
+
 PyObject* f_ColorTransform(PyObject* self, PyObject* args, PyObject* kwargs)
 {
     return NULL;
@@ -151,7 +353,40 @@ static int colortransform_setattr(PyObject * self, char* a, PyObject* o)
 {
     return 0;
 }
+CXFORM colortransform_getCXForm(PyObject*self)
+{
+    CXFormObject*cxform= 0;
+    if (!PyArg_Parse(self, "O!", &CXFormClass, &cxform)) {
+       CXFORM dummy;
+       memset(&dummy, 0, sizeof(dummy));
+       mylog("Error: wrong type for function color_getRGBA");
+       return dummy;
+    }
+    return cxform->cxform;
+}
+void colortransform_dealloc(PyObject* self)
+{
+    mylog("-%08x(%d) colortransform_dealloc", self, self->ob_refcnt);
+    PyObject_Del(self);
+}
+PyTypeObject CXFormClass = 
+{
+    PyObject_HEAD_INIT(NULL)
+    0,
+    tp_name: "ColorTransform",
+    tp_basicsize: sizeof(CXFormObject),
+    tp_itemsize: 0,
+    tp_dealloc: colortransform_dealloc,
+    tp_print: 0,
+    tp_getattr: colortransform_getattr,
+    tp_setattr: colortransform_setattr,
+};
 //----------------------------------------------------------------------------
+typedef struct {
+    PyObject_HEAD
+    GRADIENT gradient;
+} GradientObject;
+
 PyObject* f_Gradient(PyObject* self, PyObject* args, PyObject* kwargs)
 {
     return NULL;
@@ -164,32 +399,22 @@ static int gradient_setattr(PyObject * self, char* a, PyObject* o)
 {
     return 0;
 }
-//----------------------------------------------------------------------------
-
-PyTypeObject ColorClass = 
+GRADIENT gradient_getGradient(PyObject*self)
 {
-    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 = 
+    GradientObject*gradient = 0;
+    if (!PyArg_Parse(self, "O!", &gradient, &gradient)) {
+       GRADIENT dummy;
+       memset(&dummy, 0, sizeof(dummy));
+       mylog("Error: wrong type for function color_getRGBA");
+       return dummy;
+    }
+    return gradient->gradient;
+}
+void gradient_dealloc(PyObject* self)
 {
-    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,
-};
+    mylog("-%08x(%d) gradient_dealloc", self, self->ob_refcnt);
+    PyObject_Del(self);
+}
 PyTypeObject GradientClass = 
 {
     PyObject_HEAD_INIT(NULL)
@@ -197,40 +422,205 @@ PyTypeObject GradientClass =
     tp_name: "Gradient",
     tp_basicsize: sizeof(GradientObject),
     tp_itemsize: 0,
-    tp_dealloc: dummy_dealloc,
+    tp_dealloc: gradient_dealloc,
     tp_print: 0,
     tp_getattr: gradient_getattr,
     tp_setattr: gradient_setattr,
 };
-PyTypeObject CXFormClass = 
+//----------------------------------------------------------------------------
+
+typedef struct {
+    PyObject_HEAD
+    LINESTYLE ls;
+} LineStyleObject;
+
+PyObject* f_LineStyle2(RGBA color, int width) 
+{
+    LineStyleObject* self = PyObject_New(LineStyleObject, &LineStyleClass);
+    self->ls.color = color;
+    self->ls.width = width;
+    return (PyObject*)self;
+}
+PyObject* f_LineStyle3(LINESTYLE ls)
+{
+    LineStyleObject* self = PyObject_New(LineStyleObject, &LineStyleClass);
+    self->ls = ls;
+    return (PyObject*)self;
+}
+PyObject* f_LineStyle(PyObject* _self, PyObject* args, PyObject* kwargs)
+{
+    static char *kwlist[] = {"line", "color", NULL};
+    float linewidth;
+    PyObject*color;
+    if(!kwargs) {
+       if (!PyArg_ParseTuple(args, "fO!", &linewidth, &ColorClass, &color))
+           return NULL;
+    }
+    return f_LineStyle2(color_getRGBA(color), (int)(linewidth*20));
+}
+LINESTYLE linestyle_getLineStyle(PyObject*_self)
+{
+    LineStyleObject* self = (LineStyleObject*)_self;
+    return self->ls;
+}
+static PyObject* linestyle_getattr(PyObject * _self, char* a)
+{
+    LineStyleObject*self = (LineStyleObject*)_self;
+    if(!strcmp(a, "width")) {
+       return Py_BuildValue("i", self->ls.width);
+    } else if(!strcmp(a, "color")) {
+       return f_Color2(self->ls.color.r, self->ls.color.g, self->ls.color.b, self->ls.color.a);
+    }
+    return NULL;
+}
+static int linestyle_setattr(PyObject * _self, char* a, PyObject* o)
+{
+    LineStyleObject*self = (LineStyleObject*)_self;
+    if(!strcmp(a, "color")) {
+       self->ls.color = color_getRGBA(o);
+       return 0;
+    }
+    return -1;
+}
+static LINESTYLE linestyle_getlinestyle(PyObject*_self)
+{
+    LineStyleObject*self = (LineStyleObject*)_self;
+    return self->ls;
+}
+static void linestyle_dealloc(PyObject* self)
+{
+    mylog("-%08x(%d) linestyle_dealloc", self, self->ob_refcnt);
+    PyObject_Del(self);
+}
+static int linestyle_print(PyObject * _self, FILE *fi, int flags) //flags&Py_PRINT_RAW
+{
+    LineStyleObject* self = (LineStyleObject*)_self;
+    fprintf(fi, "line-%d-%02x%02x%02x%02x", self->ls.width, self->ls.color.r, self->ls.color.g, self->ls.color.b, self->ls.color.a);
+    return 0;
+}
+PyTypeObject LineStyleClass = 
 {
     PyObject_HEAD_INIT(NULL)
     0,
-    tp_name: "ColorTransform",
-    tp_basicsize: sizeof(CXFormObject),
+    tp_name: "linestyle",
+    tp_basicsize: sizeof(LineStyleObject),
     tp_itemsize: 0,
-    tp_dealloc: dummy_dealloc,
-    tp_print: 0,
-    tp_getattr: colortransform_getattr,
-    tp_setattr: colortransform_setattr,
+    tp_dealloc: linestyle_dealloc,
+    tp_print: linestyle_print,
+    tp_getattr: linestyle_getattr,
+    tp_setattr: linestyle_setattr,
 };
-PyTypeObject MatrixClass = 
+//----------------------------------------------------------------------------
+
+typedef struct {
+    PyObject_HEAD
+    FILLSTYLE fs;
+} FillStyleObject;
+
+PyObject* f_FillStyle2(FILLSTYLE fs)
+{
+    FillStyleObject* self = PyObject_New(FillStyleObject, &FillStyleClass);
+    self->fs = fs;
+    return (PyObject*)self;
+}
+PyObject* f_SolidFillStyle2(RGBA color)
+{
+    FillStyleObject* self = PyObject_New(FillStyleObject, &FillStyleClass);
+    self->fs.type = FILL_SOLID;
+    self->fs.color = color;
+    return (PyObject*)self;
+}
+PyObject* f_SolidFillStyle(PyObject* _self, PyObject* args, PyObject* kwargs)
+{
+    static char *kwlist[] = {"color", NULL};
+    PyObject*color;
+    if(!kwargs) {
+       if (!PyArg_ParseTuple(args, "O!", &ColorClass, &color))
+           return NULL;
+    }
+    return f_SolidFillStyle2(color_getRGBA(color));
+}
+FILLSTYLE fillstyle_getFillStyle(PyObject*_self)
+{
+    FillStyleObject* self = (FillStyleObject*)_self;
+    return self->fs;
+}
+static void fillstyle_dealloc(PyObject* self)
+{
+    mylog("-%08x(%d) linestyle_dealloc", self, self->ob_refcnt);
+    PyObject_Del(self);
+}
+static int fillstyle_print(PyObject * _self, FILE *fi, int flags) //flags&Py_PRINT_RAW
+{
+    FillStyleObject* self = (FillStyleObject*)_self;
+    if(self->fs.type == FILL_SOLID)
+       fprintf(fi, "fill-solid(%02x%02x%02x%02x)", self->fs.color.r, self->fs.color.g, self->fs.color.b, self->fs.color.a);
+    else
+       fprintf(fi, "fill-%02x", self->fs.type);
+    return 0;
+}
+PyObject* fillstyle_issolid(PyObject*_self, PyObject*args)
+{
+    FillStyleObject* self = (FillStyleObject*)_self;
+    int b = self->fs.type == FILL_SOLID;
+    return PyInt_FromLong(b);
+}
+static PyMethodDef FillStyleMethods[] = 
+{
+    /* Module functions */
+    {"isSolid", fillstyle_issolid, METH_VARARGS, "Queries whether this is a solid fill"},
+    {0,0,0,0}
+};
+static PyObject* fillstyle_getattr(PyObject * _self, char* a)
+{
+    FillStyleObject* self = (FillStyleObject*)_self;
+    if(!strcmp(a, "color")) {
+       return f_Color2(self->fs.color.r, self->fs.color.g, self->fs.color.b, self->fs.color.a);
+    }
+    return Py_FindMethod(FillStyleMethods, _self, a);
+}
+static int fillstyle_setattr(PyObject * _self, char* a, PyObject* o)
+{
+    FillStyleObject*self = (FillStyleObject*)_self;
+    if(!strcmp(a, "color")) {
+       self->fs.color = color_getRGBA(o);
+       return 0;
+    }
+    return -1;
+}
+
+PyTypeObject FillStyleClass = 
 {
     PyObject_HEAD_INIT(NULL)
     0,
-    tp_name: "Matrix",
-    tp_basicsize: sizeof(MatrixObject),
+    tp_name: "fillstyle",
+    tp_basicsize: sizeof(FillStyleObject),
     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)
+    tp_dealloc: fillstyle_dealloc,
+    tp_print: fillstyle_print,
+    tp_getattr: fillstyle_getattr,
+    tp_setattr: fillstyle_setattr,
 };
+//----------------------------------------------------------------------------
+static PyMethodDef primitive_methods[] = 
+{
+    {"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."},
+    {"SolidFillStyle", (PyCFunction)f_SolidFillStyle, METH_KEYWORDS, "Creates a new solid fill style."},
+    {"LineStyle", (PyCFunction)f_SolidFillStyle, METH_KEYWORDS, "Creates a new line style."},
+    {NULL, NULL, 0, NULL}
+};
+
+PyMethodDef* primitive_getMethods()
+{
+    GradientClass.ob_type = &PyType_Type;
+    CXFormClass.ob_type = &PyType_Type;
+    BBoxClass.ob_type = &PyType_Type;
+    MatrixClass.ob_type = &PyType_Type;
+    return primitive_methods;
+}
+
+