X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fpython%2Fgfx.c;h=9093a7804331b89c9950cfaae9e0c3f54bc2bdeb;hb=4a566feb5f1074db505f5f8a78c7fdf487d94b9a;hp=5bc2068064b20a11c0d0296b5ad44a4989a38b91;hpb=cff493c8c3d14392786e3415478faf62423f71b5;p=swftools.git diff --git a/lib/python/gfx.c b/lib/python/gfx.c index 5bc2068..9093a78 100644 --- a/lib/python/gfx.c +++ b/lib/python/gfx.c @@ -23,10 +23,16 @@ #include #include #undef HAVE_STAT +#include "../../config.h" +#include "../gfxtools.h" #include "../devices/swf.h" #include "../devices/render.h" +#include "../devices/ocr.h" #include "../devices/rescale.h" #include "../devices/text.h" +#ifdef USE_OPENGL +#include "../devices/opengl.h" +#endif #include "../pdf/pdf.h" #include "../readers/swf.h" #include "../readers/image.h" @@ -124,6 +130,182 @@ static PyObject* output_startpage(PyObject* _self, PyObject* args, PyObject* kwa self->output_device->startpage(self->output_device, width, height); return PY_NONE; } + +/* as the definition of the python image type comes from another module (not + included here, reproduce the necessary structure and extract the image + without using the type definition */ +typedef struct { + PyObject_HEAD + gfximage_t*image; + PyObject* strrepr; +} ImageObject; +static gfximage_t*toImage(PyObject*_bitmap) +{ + if(!_bitmap || !_bitmap->ob_type->tp_name || strcmp(_bitmap->ob_type->tp_name, "Image")) { + return PY_ERROR("Second argument to fillbitmap must be an image"); + } + ImageObject*bitmap = (ImageObject*)_bitmap; + return bitmap->image; +} + +static gfxline_t*toLine(PyObject*_line) +{ + int t; + int num = PyList_Size(_line); + gfxline_t first; + first.next = 0; + gfxline_t*last=&first; + for(t=0;tnext = l; + last = l; + if(type[0]=='m') { + l->type = gfx_moveTo; + if(size!=3) + return PY_ERROR("need 2 values for move"); + l->x = PyFloat_AsDouble(PyTuple_GetItem(p, 1)); + l->y = PyFloat_AsDouble(PyTuple_GetItem(p, 2)); + } else if(type[0]=='l') { + l->type = gfx_lineTo; + if(size!=3) + return PY_ERROR("need 2 values for line"); + l->x = PyFloat_AsDouble(PyTuple_GetItem(p, 1)); + l->y = PyFloat_AsDouble(PyTuple_GetItem(p, 2)); + } else if(type[0]=='s') { + l->type = gfx_splineTo; + if(size!=5) + return PY_ERROR("need 4 values for spline"); + l->x = PyFloat_AsDouble(PyTuple_GetItem(p, 1)); + l->y = PyFloat_AsDouble(PyTuple_GetItem(p, 2)); + l->sx = PyFloat_AsDouble(PyTuple_GetItem(p, 3)); + l->sy = PyFloat_AsDouble(PyTuple_GetItem(p, 4)); + } else { + PY_ERROR("Unknown line code '%s'", l->type); + } + } + return first.next; +} + +PyDoc_STRVAR(output_fillbitmap_doc, \ +"fillbitmap()\n\n" +"fill a polygon with a bitmap pattern\n" +); +static PyObject* output_fillbitmap(PyObject* _self, PyObject* args, PyObject* kwargs) +{ + OutputObject* self = (OutputObject*)_self; + PyObject*_line=0; + PyObject*_bitmap=0; + static char *kwlist[] = {"line", "bitmap", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O", kwlist, &PyList_Type, &_line, &_bitmap)) + return NULL; + + gfximage_t*image = toImage(_bitmap); + if(!image) + return 0; + + gfxline_t*line = toLine(_line); + if(!line) + return 0; + + /* TODO */ + gfxmatrix_t m; + memset(&m, 0, sizeof(gfxmatrix_t)); + m.m00 = m.m11 = 1.0; + + self->output_device->fillbitmap(self->output_device, line, image, &m, 0); + gfxline_free(line); + return PY_NONE; +} + +PyDoc_STRVAR(output_fill_doc, \ +"fill()\n\n" +"fill a polygon with a color\n" +); +static PyObject* output_fill(PyObject* _self, PyObject* args, PyObject* kwargs) +{ + OutputObject* self = (OutputObject*)_self; + PyObject*_line=0; + PyObject*_bitmap=0; + static char *kwlist[] = {"line", "color", NULL}; + + PyObject* color=0; + + int a=255,r=0,g=0,b=0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O", kwlist, &PyList_Type, &_line, &color)) + return NULL; + + if(!PyArg_ParseTuple(color, "iiii:color", &a, &r, &g, &b)) { + return NULL; + } + + gfxcolor_t c; + c.r = r; c.g = g; c.b = b; c.a = a; + + gfxline_t*line = toLine(_line); + if(!line) + return 0; + + /* TODO */ + gfxmatrix_t m; + memset(&m, 0, sizeof(gfxmatrix_t)); + m.m00 = m.m11 = 1.0; + + self->output_device->fill(self->output_device, line, &c); + gfxline_free(line); + return PY_NONE; +} + +PyDoc_STRVAR(output_stroke_doc, \ +"stroke()\n\n" +"stroke a polygon with a color\n" +); +static PyObject* output_stroke(PyObject* _self, PyObject* args, PyObject* kwargs) +{ + OutputObject* self = (OutputObject*)_self; + PyObject*_line=0; + PyObject*_bitmap=0; + static char *kwlist[] = {"line", "width", "color", NULL}; + + PyObject* color=0; + + int a=255,r=0,g=0,b=0; + double width = 1.0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!fO", kwlist, &PyList_Type, &_line, &width, &color)) + return NULL; + + if(!PyArg_ParseTuple(color, "iiii:color", &a, &r, &g, &b)) { + return NULL; + } + + gfxcolor_t c; + c.r = r; c.g = g; c.b = b; c.a = a; + + gfxline_t*line = toLine(_line); + if(!line) + return 0; + + self->output_device->stroke(self->output_device, line, width, &c, + /*TODO*/ gfx_capRound, gfx_joinRound, 0.0); + gfxline_free(line); + return PY_NONE; +} + PyDoc_STRVAR(output_endpage_doc, \ "endpage()\n\n" "Ends a page in the output device. This function should be called\n" @@ -170,6 +352,27 @@ static PyObject* f_createSWF(PyObject* parent, PyObject* args, PyObject* kwargs) return (PyObject*)self; } +PyDoc_STRVAR(f_createOCR_doc, \ +"OCR()\n\n" +"Creates a device which processes documents using OCR (optical\n" +"character recognition).\n" +"This is handy for e.g. extracting fulltext from PDF documents\n" +"which have broken fonts, and where hence the \"PlainText\"\n" +"device doesn't work.\n" +); +static PyObject* f_createOCR(PyObject* parent, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {NULL}; + if (args && !PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist)) + return NULL; + OutputObject*self = PyObject_New(OutputObject, &OutputClass); + + self->output_device = malloc(sizeof(gfxdevice_t)); + gfxdevice_ocr_init(self->output_device); + return (PyObject*)self; +} + + PyDoc_STRVAR(f_createImageList_doc, \ "ImageList()\n\n" "Creates a device which renders documents to bitmaps.\n" @@ -207,10 +410,30 @@ static PyObject* f_createPlainText(PyObject* parent, PyObject* args, PyObject* k return (PyObject*)self; } +#ifdef USE_OPENGL +PyDoc_STRVAR(f_createOpenGL_doc, \ +"OpenGL()\n\n" +"Creates a device which renders everything to OpenGL.\n" +"Can be used for desktop display and debugging.\n" +"This device is not available on all systems.\n" +); +static PyObject* f_createOpenGL(PyObject* parent, PyObject* args, PyObject* kwargs) +{ + static char *kwlist[] = {NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist)) + return NULL; + OutputObject*self = PyObject_New(OutputObject, &OutputClass); + + self->output_device = malloc(sizeof(gfxdevice_t)); + gfxdevice_opengl_init(self->output_device); + return (PyObject*)self; +} +#endif + static PyObject*callback_python(char*function, gfxdevice_t*dev, const char*format, ...) { OutputObject*self = (OutputObject*)dev->internal; - + if(!PyObject_HasAttrString(self->pyobj, function)) return PY_NONE; @@ -231,10 +454,10 @@ static PyObject*callback_python(char*function, gfxdevice_t*dev, const char*forma void* ptr = va_arg(ap, void*); gfxcolor_t*col = (gfxcolor_t*)ptr; PyObject*colobj = PyTuple_New(4); - PyTuple_SetItem(colobj, 0, PyInt_FromLong(col->r)); - PyTuple_SetItem(colobj, 1, PyInt_FromLong(col->g)); - PyTuple_SetItem(colobj, 2, PyInt_FromLong(col->b)); - PyTuple_SetItem(colobj, 3, PyInt_FromLong(col->a)); + PyTuple_SetItem(colobj, 0, PyInt_FromLong(col->a)); + PyTuple_SetItem(colobj, 1, PyInt_FromLong(col->r)); + PyTuple_SetItem(colobj, 2, PyInt_FromLong(col->g)); + PyTuple_SetItem(colobj, 3, PyInt_FromLong(col->b)); PyTuple_SetItem(tuple, pos, colobj); } else if(p=='l') { void* ptr = va_arg(ap, void*); @@ -391,6 +614,7 @@ static PyObject* f_createPassThrough(PyObject* parent, PyObject* args, PyObject* OutputObject*self = PyObject_New(OutputObject, &OutputClass); self->pyobj = obj; + Py_INCREF(obj); self->output_device = malloc(sizeof(gfxdevice_t)); memset(self->output_device, 0, sizeof(gfxdevice_t)); self->output_device->name = strdup("passthrough"); @@ -418,6 +642,9 @@ static PyMethodDef output_methods[] = /* Output functions */ {"save", (PyCFunction)output_save, METH_KEYWORDS, output_save_doc}, {"startpage", (PyCFunction)output_startpage, METH_KEYWORDS, output_startpage_doc}, + {"fill", (PyCFunction)output_fill, METH_KEYWORDS, output_fill_doc}, + {"fillbitmap", (PyCFunction)output_fillbitmap, METH_KEYWORDS, output_fillbitmap_doc}, + {"stroke", (PyCFunction)output_stroke, METH_KEYWORDS, output_stroke_doc}, {"endpage", (PyCFunction)output_endpage, METH_KEYWORDS, output_endpage_doc}, {"setparameter", (PyCFunction)output_setparameter, METH_KEYWORDS, output_setparameter_doc}, {0,0,0,0} @@ -726,6 +953,8 @@ static PyObject* f_open(PyObject* parent, PyObject* args, PyObject* kwargs) type = "image"; if(strchr("pP", filename[l-3]) && strchr("nN", filename[l-2]) && strchr("gG", filename[l-1])) type = "image"; + if(strchr("sS", filename[l-3]) && strchr("wW", filename[l-2]) && strchr("fF", filename[l-1])) + type = "swf"; } else if(filename[l-5]=='.') { type = "image"; } @@ -734,9 +963,9 @@ static PyObject* f_open(PyObject* parent, PyObject* args, PyObject* kwargs) if(!strcmp(type,"pdf")) self->doc = pdfdriver->open(pdfdriver,filename); - else if(!strcmp(type, "image")) + else if(!strcmp(type, "image") || !strcmp(type, "img")) self->doc = imagedriver->open(imagedriver, filename); - else if(!strcmp(type, "swf")) + else if(!strcmp(type, "swf") || !strcmp(type, "SWF")) self->doc = swfdriver->open(imagedriver, filename); else return PY_ERROR("Unknown type %s", type); @@ -946,9 +1175,13 @@ static PyMethodDef pdf2swf_methods[] = /* devices */ {"SWF", (PyCFunction)f_createSWF, METH_KEYWORDS, f_createSWF_doc}, + {"OCR", (PyCFunction)f_createOCR, METH_KEYWORDS, f_createOCR_doc}, {"ImageList", (PyCFunction)f_createImageList, METH_KEYWORDS, f_createImageList_doc}, {"PlainText", (PyCFunction)f_createPlainText, METH_KEYWORDS, f_createPlainText_doc}, {"PassThrough", (PyCFunction)f_createPassThrough, METH_KEYWORDS, f_createPassThrough_doc}, +#ifdef USE_OPENGL + {"OpenGL", (PyCFunction)f_createOpenGL, METH_KEYWORDS, f_createOpenGL_doc}, +#endif /* sentinel */ {0, 0, 0, 0}