Subversion Repositories Scribus

Rev

Rev 2601 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1405 subik 1
#include "objimageexport.h"
2
#include "cmdutil.h"
3
 
4
#include <structmember.h>
5
#include <qfileinfo.h>
6
#include <vector>
7
 
8
typedef struct
9
{
10
        PyObject_HEAD
11
        PyObject *name; // string - filename
12
        PyObject *type; // string - image type (PNG, JPEG etc.)
13
        PyObject *allTypes; // list - available types
14
        int dpi; // DPI of the bitmap
15
        int scale; // how is bitmap scaled 100 = 100%
16
        int quality; // quality/compression <1; 100>
17
} ImageExport;
18
 
19
 
20
static void ImageExport_dealloc(ImageExport* self)
21
{
22
        Py_XDECREF(self->name);
23
        Py_XDECREF(self->type);
24
        Py_XDECREF(self->allTypes);
25
        self->ob_type->tp_free((PyObject *)self);
26
}
27
 
28
static PyObject * ImageExport_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
29
{
30
        if(!checkHaveDocument())
31
                return NULL;
32
 
33
        ImageExport *self;
34
        self = (ImageExport *)type->tp_alloc(type, 0);
35
        if (self != NULL) {
2587 subik 36
                self->name = PyString_FromString("ImageExport.png");
1405 subik 37
                self->type = PyString_FromString("PNG");
38
                self->allTypes = PyList_New(0);
39
                self->dpi = 72;
40
                self->scale = 100;
41
                self->quality = 100;
42
        }
43
        return (PyObject *) self;
44
}
45
 
46
static int ImageExport_init(ImageExport *self, PyObject *args, PyObject *kwds)
47
{
48
        return 0;
49
}
50
 
51
static PyMemberDef ImageExport_members[] = {
52
        {const_cast<char*>("dpi"), T_INT, offsetof(ImageExport, dpi), 0, imgexp_dpi__doc__},
53
        {const_cast<char*>("scale"), T_INT, offsetof(ImageExport, scale), 0, imgexp_scale__doc__},
54
        {const_cast<char*>("quality"), T_INT, offsetof(ImageExport, quality), 0, imgexp_quality__doc__},
55
        {NULL, 0, 0, 0, NULL} // sentinel
56
};
57
 
58
static PyObject *ImageExport_getName(ImageExport *self, void *closure)
59
{
60
        Py_INCREF(self->name);
61
        return self->name;
62
}
63
 
64
static int ImageExport_setName(ImageExport *self, PyObject *value, void *closure)
65
{
66
        if (!PyString_Check(value)) {
67
                PyErr_SetString(PyExc_TypeError, QObject::tr("The filename must be a string.", "python error"));
68
                return -1;
69
        }
2587 subik 70
        if (PyString_Size(value) < 1)
71
        {
72
                PyErr_SetString(PyExc_TypeError, "The filename should not be empty string.");
73
                return -1;
74
        }
1405 subik 75
        Py_DECREF(self->name);
76
        Py_INCREF(value);
77
        self->name = value;
78
        return 0;
79
}
80
 
81
static PyObject *ImageExport_getType(ImageExport *self, void *closure)
82
{
83
        Py_INCREF(self->type);
84
        return self->type;
85
}
86
 
87
static int ImageExport_setType(ImageExport *self, PyObject *value, void *closure)
88
{
89
        if (value == NULL) {
90
                PyErr_SetString(PyExc_TypeError, QObject::tr("Cannot delete image type settings.", "python error"));
91
                return -1;
92
        }
93
        if (!PyString_Check(value)) {
94
                PyErr_SetString(PyExc_TypeError, QObject::tr("The image type must be a string.", "python error"));
95
                return -1;
96
        }
97
        Py_DECREF(self->type);
98
        Py_INCREF(value);
99
        self->type = value;
100
        return 0;
101
}
102
 
103
static PyObject *ImageExport_getAllTypes(ImageExport *self, void *closure)
104
{
105
        PyObject *l;
106
        int pos = 0;
107
        QStringList list = QImage::outputFormatList();
108
        l = PyList_New(list.count());
109
        for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
110
        {
111
                PyList_SetItem(l, pos, PyString_FromString((*it).latin1()));
112
                ++pos;
113
        }
114
        return l;
115
}
116
 
117
static int ImageExport_setAllTypes(ImageExport *self, PyObject *value, void *closure)
118
{
119
        PyErr_SetString(PyExc_ValueError, QObject::tr("'allTypes' attribute is READ-ONLY", "python error"));
120
        return -1;
121
}
122
 
123
static PyGetSetDef ImageExport_getseters [] = {
124
        {const_cast<char*>("name"), (getter)ImageExport_getName, (setter)ImageExport_setName, imgexp_filename__doc__, NULL},
125
        {const_cast<char*>("type"), (getter)ImageExport_getType, (setter)ImageExport_setType, imgexp_type__doc__, NULL},
126
        {const_cast<char*>("allTypes"), (getter)ImageExport_getAllTypes, (setter)ImageExport_setAllTypes, imgexp_alltypes__doc__, NULL},
127
        {NULL, NULL, NULL, NULL, NULL}  // sentinel
128
};
129
 
130
static PyObject *ImageExport_save(ImageExport *self)
131
{
132
        if(!checkHaveDocument())
133
                return NULL;
2584 subik 134
 
2611 subik 135
        /* a little magic here - I need to compute the "maxGr" value...
136
        * We need to know the right size of the page for landscape,
137
        * portrait and user defined sizes.
138
        */
139
        double pixmapSize;
140
        (Carrier->doc->PageH > Carrier->doc->PageB)
141
                        ? pixmapSize = Carrier->doc->PageH
142
                        : pixmapSize = Carrier->doc->PageB;
143
        QPixmap pixmap = Carrier->view->PageToPixmap(Carrier->doc->ActPage->PageNr, qRound(pixmapSize * self->scale * (self->dpi / 72.0) / 100.0));
1405 subik 144
        QImage im = pixmap.convertToImage();
2584 subik 145
        int dpm = qRound(100.0 / 2.54 * self->dpi);
146
        im.setDotsPerMeterY(dpm);
147
        im.setDotsPerMeterX(dpm);
148
        if (!im.save(PyString_AsString(self->name), PyString_AsString(self->type), self->quality))
1405 subik 149
        {
150
                PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error"));
151
                return NULL;
152
        }
153
        Py_INCREF(Py_True); // return True not None for backward compat
154
        return Py_True;
155
}
156
 
157
static PyObject *ImageExport_saveAs(ImageExport *self, PyObject *args)
158
{
159
        char* value;
160
        if(!checkHaveDocument())
161
                return NULL;
162
        if (!PyArg_ParseTuple(args, "es", "utf-8", &value))
163
                return NULL;
2611 subik 164
 
165
        /* a little magic here - I need to compute the "maxGr" value...
166
        * We need to know the right size of the page for landscape,
167
        * portrait and user defined sizes.
168
        */
169
        double pixmapSize;
170
        (Carrier->doc->PageH > Carrier->doc->PageB)
171
                        ? pixmapSize = Carrier->doc->PageH
172
                        : pixmapSize = Carrier->doc->PageB;
173
        QPixmap pixmap = Carrier->view->PageToPixmap(Carrier->doc->ActPage->PageNr, qRound(pixmapSize * self->scale * (self->dpi / 72.0) / 100.0));
1405 subik 174
        QImage im = pixmap.convertToImage();
2601 subik 175
        int dpm = qRound(100.0 / 2.54 * self->dpi);
176
        im.setDotsPerMeterY(dpm);
177
        im.setDotsPerMeterX(dpm);
2584 subik 178
        if (!im.save(value, PyString_AsString(self->type), self->quality))
1405 subik 179
        {
180
                PyErr_SetString(ScribusException, QObject::tr("Failed to export image", "python error"));
181
                return NULL;
182
        }
183
        Py_INCREF(Py_True); // return True not None for backward compat
184
        return Py_True;
185
}
186
 
187
static PyMethodDef ImageExport_methods[] = {
188
        {const_cast<char*>("save"), (PyCFunction)ImageExport_save, METH_NOARGS, imgexp_save__doc__},
189
        {const_cast<char*>("saveAs"), (PyCFunction)ImageExport_saveAs, METH_VARARGS, imgexp_saveas__doc__},
190
        {NULL, (PyCFunction)(0), 0, NULL} // sentinel
191
};
192
 
193
PyTypeObject ImageExport_Type = {
194
        PyObject_HEAD_INIT(NULL)   // PyObject_VAR_HEAD
195
        0,
196
        const_cast<char*>("ImageExport"), // char *tp_name; /* For printing, in format "<module>.<name>" */
197
        sizeof(ImageExport),   // int tp_basicsize, /* For allocation */
198
        0,  // int tp_itemsize; /* For allocation */
199
        (destructor) ImageExport_dealloc, //     destructor tp_dealloc;
200
        0, //    printfunc tp_print;
201
        0, //    getattrfunc tp_getattr;
202
        0, //    setattrfunc tp_setattr;
203
        0, //    cmpfunc tp_compare;
204
        0, //    reprfunc tp_repr;
205
        0, //    PyNumberMethods *tp_as_number;
206
        0, //    PySequenceMethods *tp_as_sequence;
207
        0, //    PyMappingMethods *tp_as_mapping;
208
        0, //    hashfunc tp_hash;
209
        0, //    ternaryfunc tp_call;
210
        0, //    reprfunc tp_str;
211
        0, //    getattrofunc tp_getattro;
212
        0, //    setattrofunc tp_setattro;
213
        0, //    PyBufferProcs *tp_as_buffer;
214
        Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, // long tp_flags;
215
        imgexp__doc__, // char *tp_doc; /* Documentation string */
216
        0, //    traverseproc tp_traverse;
217
        0, //    inquiry tp_clear;
218
        0, //    richcmpfunc tp_richcompare;
219
        0, //    long tp_weaklistoffset;
220
        0, //    getiterfunc tp_iter;
221
        0, //    iternextfunc tp_iternext;
222
        ImageExport_methods, //  struct PyMethodDef *tp_methods;
223
        ImageExport_members, //  struct PyMemberDef *tp_members;
224
        ImageExport_getseters, //        struct PyGetSetDef *tp_getset;
225
        0, //    struct _typeobject *tp_base;
226
        0, //    PyObject *tp_dict;
227
        0, //    descrgetfunc tp_descr_get;
228
        0, //    descrsetfunc tp_descr_set;
229
        0, //    long tp_dictoffset;
230
        (initproc)ImageExport_init, //   initproc tp_init;
231
        0, //    allocfunc tp_alloc;
232
        ImageExport_new, //      newfunc tp_new;
233
        0, //    freefunc tp_free; /* Low-level free-memory routine */
234
        0, //    inquiry tp_is_gc; /* For PyObject_IS_GC */
235
        0, //    PyObject *tp_bases;
236
        0, //    PyObject *tp_mro; /* method resolution order */
237
        0, //    PyObject *tp_cache;
238
        0, //    PyObject *tp_subclasses;
239
        0, //    PyObject *tp_weaklist;
240
        0, //    destructor tp_del;
241
 
242
#ifdef COUNT_ALLOCS
243
        /* these must be last and never explicitly initialized */
244
        //      int tp_allocs;
245
        //      int tp_frees;
246
        //      int tp_maxalloc;
247
        //      struct _typeobject *tp_next;
248
#endif
249
};