Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
14088 fschmid 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
 
8
#include <QFile>
9
#include <QList>
10
#include <QDebug>
11
#include <QVector>
12
 
13
#include <cmath>
14
#include <cstdlib>
15
 
16
#include <stdio.h>
17
#include "scimgdataloader_wpg.h"
18
#include "plugins/wpgimplugin/wpg/WPGStreamImplementation.h"
19
 
20
ScrPainterIm::ScrPainterIm(): libwpg::WPGPaintInterface()
21
{
22
}
23
 
24
void ScrPainterIm::startGraphics(double width, double height)
25
{
26
        currentPen = QPen(Qt::black, 1);
27
        currentBrush = Qt::black;
28
        Coords = QPainterPath();
29
        *image = QImage(qRound(width * 72), qRound(height * 72), QImage::Format_ARGB32);
30
        image->fill(qRgba(255, 255, 255, 255));
31
        imagePainter.begin(image);
32
        imagePainter.setRenderHint(QPainter::Antialiasing , true);
33
        fillrule = true;
34
        gradientAngle = 0.0;
35
        isGradient = false;
36
        fillSet = false;
37
        strokeSet = false;
38
        currentGradient = QLinearGradient();
39
//      qDebug() << "Start Graphics" << qRound(width * 72) << qRound(height * 72);
40
}
41
 
42
void ScrPainterIm::endGraphics()
43
{
44
        imagePainter.end();
45
//      qDebug() << "End Graphics";
46
}
47
 
48
void ScrPainterIm::startLayer(unsigned int id)
49
{
50
}
51
 
52
void ScrPainterIm::endLayer(unsigned int id)
53
{
54
}
55
 
56
void ScrPainterIm::setPen(const libwpg::WPGPen& pen)
57
{
58
        QVector<double> dashArray;
59
        dashArray.clear();
60
        Qt::PenJoinStyle lineJoin;
61
        Qt::PenCapStyle lineEnd;
62
        double LineW = 72 * pen.width;
63
        QColor foreColor = QColor(pen.foreColor.red, pen.foreColor.green, pen.foreColor.blue, 255 - pen.foreColor.alpha);
64
        if(!pen.solid)
65
        {
66
                dashArray.clear();
67
                for(unsigned i = 0; i < pen.dashArray.count(); i++)
68
                {
69
                        dashArray.append(pen.dashArray.at(i)*LineW);
70
                }
71
        }
72
        switch (pen.joinstyle)
73
        {
74
                case 1:
75
                        lineJoin = Qt::BevelJoin;
76
                        break;
77
                case 2:
78
                        lineJoin = Qt::MiterJoin;
79
                        break;
80
                case 3:
81
                        lineJoin = Qt::RoundJoin;
82
                        break;
83
                default:
84
                        lineJoin = Qt::MiterJoin;
85
                        break;
86
        }
87
        switch (pen.capstyle)
88
        {
89
                case 0:
90
                        lineEnd = Qt::FlatCap;
91
                        break;
92
                case 1:
93
                        lineEnd = Qt::RoundCap;
94
                        break;
95
                case 2:
96
                        lineEnd = Qt::SquareCap;
97
                        break;
98
                default:
99
                        lineEnd = Qt::FlatCap;
100
                        break;
101
        }
102
        if(!pen.solid)
103
        {
104
                currentPen = QPen(foreColor, LineW, Qt::SolidLine, lineEnd, lineJoin);
105
                currentPen.setDashPattern(dashArray);
106
        }
107
        else
108
                currentPen = QPen(foreColor, LineW, Qt::SolidLine, lineEnd, lineJoin);
109
        strokeSet = true;
110
//      qDebug() << "Set Pen" << pen.foreColor.red << pen.foreColor.green << pen.foreColor.blue << pen.foreColor.alpha;
111
}
112
 
113
void ScrPainterIm::setBrush(const libwpg::WPGBrush& brush)
114
{
115
        isGradient = false;
116
        if(brush.style == libwpg::WPGBrush::Solid)
117
        {
118
                currentBrush = QColor(brush.foreColor.red, brush.foreColor.green, brush.foreColor.blue, 255 - brush.foreColor.alpha);
119
        }
120
        else if (brush.style == libwpg::WPGBrush::Gradient)
121
        {
122
                gradientAngle = brush.gradient.angle();
123
                isGradient = true;
124
                currentGradient = QLinearGradient();
125
                for(unsigned c = 0; c < brush.gradient.count(); c++)
126
                {
127
                        QColor stopC = QColor(brush.gradient.stopColor(c).red, brush.gradient.stopColor(c).green, brush.gradient.stopColor(c).blue);
14090 fschmid 128
                        double pos = qBound(0.0, fabs(brush.gradient.stopOffset(c)), 1.0);
129
                        currentGradient.setColorAt(pos, stopC);
14088 fschmid 130
                }
131
        }
132
        else if (brush.style == libwpg::WPGBrush::NoBrush)
133
                currentBrush = QColor(Qt::NoBrush);
134
        fillSet = true;
135
}
136
 
137
void ScrPainterIm::setFillRule(FillRule rule)
138
{
139
        if(rule == libwpg::WPGPaintInterface::WindingFill)
140
                fillrule = false;
141
        else
142
                fillrule = true;
143
//      qDebug() << "Fill Rule " << fillrule;
144
}
145
 
146
void ScrPainterIm::drawRectangle(const libwpg::WPGRect& rect, double rx, double ry)
147
{
148
        imagePainter.setBrush(currentBrush);
149
        imagePainter.setPen(currentPen);
150
        QRectF rr = QRectF(rect.x1 * 72, rect.y1 * 72, rect.width() * 72, rect.height() * 72);
151
        if (isGradient)
152
        {
153
                QTransform m1;
154
                m1.rotate(-gradientAngle);
155
                currentGradient.setStart(rr.x(), rr.y());
156
                QPointF target = m1.map(QPointF(rr.x(), rr.bottom()));
157
                currentGradient.setFinalStop(target);
158
                imagePainter.setBrush(currentGradient);
159
        }
160
        if ((rx > 0) || (ry > 0))
161
                imagePainter.drawRoundedRect(rr, 72 * rx, 72 * ry);
162
        else
163
                imagePainter.drawRect(rr);
164
//      qDebug() << "Draw Rect " << rr;
165
}
166
 
167
void ScrPainterIm::drawEllipse(const libwpg::WPGPoint& center, double rx, double ry)
168
{
169
        imagePainter.setBrush(currentBrush);
170
        imagePainter.setPen(currentPen);
171
        QRectF rr = QRectF(0, 0, rx * 144.0, ry * 144.0);
172
        if (isGradient)
173
        {
174
                QTransform m1;
175
                m1.rotate(-gradientAngle);
176
                currentGradient.setStart(rr.x(), rr.y());
177
                QPointF target = m1.map(QPointF(rr.x(), rr.bottom()));
178
                currentGradient.setFinalStop(target);
179
                imagePainter.setBrush(currentGradient);
180
        }
181
        rr.translate(72*(center.x - rx), 72*(center.y - ry));
182
        imagePainter.drawEllipse(rr);
183
//      qDebug() << "Draw Ellipse" << rr;
184
}
185
 
186
void ScrPainterIm::drawPolygon(const libwpg::WPGPointArray& vertices, bool closed)
187
{
188
        if(vertices.count() < 2)
189
                return;
190
        imagePainter.setBrush(currentBrush);
191
        imagePainter.setPen(currentPen);
192
        Coords = QPainterPath();
193
        Coords.moveTo(72 * vertices[0].x, 72 * vertices[0].y);
194
        for(unsigned i = 1; i < vertices.count(); i++)
195
        {
196
                Coords.lineTo(72 * vertices[i].x, 72 * vertices[i].y);
197
        }
198
        if (isGradient)
199
        {
200
                QRectF rr = Coords.boundingRect();
201
                QTransform m1;
202
                m1.rotate(-gradientAngle);
203
                currentGradient.setStart(rr.x(), rr.y());
204
                QPointF target = m1.map(QPointF(rr.x(), rr.bottom()));
205
                currentGradient.setFinalStop(target);
206
                imagePainter.setBrush(currentGradient);
207
        }
208
        if (!closed)
209
                imagePainter.setBrush(Qt::NoBrush);
210
        else
211
                Coords.closeSubpath();
212
        imagePainter.drawPath(Coords);
213
//      qDebug() << "Draw Polygon";
214
}
215
 
216
void ScrPainterIm::drawPath(const libwpg::WPGPath& path)
217
{
218
        Coords = QPainterPath();
219
        for(unsigned i = 0; i < path.count(); i++)
220
        {
221
                libwpg::WPGPathElement element = path.element(i);
222
                libwpg::WPGPoint point = element.point;
223
                switch(element.type)
224
                {
225
                        case libwpg::WPGPathElement::MoveToElement:
226
                                Coords.moveTo(72 * point.x, 72 * point.y);
227
                                break;
228
                        case libwpg::WPGPathElement::LineToElement:
229
                                Coords.lineTo(72 * point.x, 72 * point.y);
230
                                break;
231
                        case libwpg::WPGPathElement::CurveToElement:
232
                                Coords.cubicTo(72*element.extra1.x, 72*element.extra1.y, 72*element.extra2.x, 72*element.extra2.y, 72 * point.x, 72 * point.y);
233
                                break;
234
                        default:
235
                                break;
236
                }
237
        }
238
        if (!path.filled)
239
                imagePainter.setBrush(Qt::NoBrush);
240
        else
241
        {
242
                if (isGradient)
243
                {
244
                        QRectF rr = Coords.boundingRect();
245
                        QTransform m1;
246
                        m1.rotate(-gradientAngle);
247
                        currentGradient.setStart(rr.x(), rr.y());
248
                        QPointF target = m1.map(QPointF(rr.x(), rr.bottom()));
249
                        currentGradient.setFinalStop(target);
250
                        imagePainter.setBrush(currentGradient);
251
                }
252
                else
253
                        imagePainter.setBrush(currentBrush);
254
        }
255
        if (!path.framed)
256
                        imagePainter.setPen(Qt::NoPen);
257
                else
258
                        imagePainter.setPen(currentPen);
259
        if(path.closed)
260
                Coords.closeSubpath();
261
        imagePainter.drawPath(Coords);
262
//      qDebug() << "Draw Path" << currentPen << currentBrush;
263
}
264
 
265
void ScrPainterIm::drawBitmap(const libwpg::WPGBitmap& bitmap, double hres, double vres)
266
{
267
        QImage img = QImage(bitmap.width(), bitmap.height(), QImage::Format_RGB32);
268
        for(int x = 0; x < bitmap.width(); x++)
269
        {
270
                for(int y = 0; y < bitmap.height(); y++)
271
                {
272
                        libwpg::WPGColor color = bitmap.pixel(x, y);
273
                        img.setPixel(x, y, qRgb(color.red, color.green, color.blue));
274
                }
275
        }
276
        double w = (bitmap.rect.x2 - bitmap.rect.x1) * 72.0;
277
        double h = (bitmap.rect.y2 - bitmap.rect.y1) * 72.0;
278
        imagePainter.drawImage(QRectF(bitmap.rect.x1 * 72, bitmap.rect.y1 * 72, w, h), img);
279
//      qDebug() << "Draw Bitmap";
280
}
281
 
282
void ScrPainterIm::drawImageObject(const libwpg::WPGBinaryData& /*binaryData*/)
283
{
284
//      qDebug() << "drawBinaryData";
285
}
286
 
287
 
288
ScImgDataLoader_WPG::ScImgDataLoader_WPG(void) : ScImgDataLoader()
289
{
290
        initSupportedFormatList();
291
}
292
 
293
void ScImgDataLoader_WPG::initSupportedFormatList(void)
294
{
295
        m_supportedFormats.clear();
296
        m_supportedFormats.append( "wpg" );
297
}
298
 
299
bool ScImgDataLoader_WPG::preloadAlphaChannel(const QString& fn, int /*page*/, int res, bool& hasAlpha)
300
{
301
        initialize();
302
        hasAlpha = false;
303
        return true;
304
}
305
 
306
void ScImgDataLoader_WPG::loadEmbeddedProfile(const QString& fn, int /*page*/)
307
{
308
        m_embeddedProfile.resize(0);
309
        m_profileComponents = 0;
310
}
311
 
312
bool ScImgDataLoader_WPG::loadPicture(const QString& fn, int /*page*/, int /*res*/, bool /*thumbnail*/)
313
{
314
        QFile file(fn);
315
        if ( !file.exists() )
316
        {
317
                qDebug() << "File " << QFile::encodeName(fn).data() << " does not exist" << endl;
318
                return false;
319
        }
320
        if ( !file.open( QIODevice::ReadOnly ) )
321
        {
322
                qDebug() << "Cannot open file " << QFile::encodeName(fn).data() << endl;
323
                return false;
324
        }
325
        QByteArray ba = file.readAll();
326
        file.close();
327
        initialize();
328
 
329
        libwpg::WPGMemoryStream input(ba.constData(), ba.size());
330
        if (!libwpg::WPGraphics::isSupported(&input))
331
        {
332
                fprintf(stderr, "ERROR: Unsupported file format (unsupported version) or file is encrypted!\n");
333
                return false;
334
        }
335
        ScrPainterIm painter;
336
        m_image = QImage();
337
        painter.image = &m_image;
338
        libwpg::WPGraphics::parse(&input, &painter);
339
        m_imageInfoRecord.type = ImageTypeOther;
340
        m_imageInfoRecord.exifDataValid = false;
341
        m_imageInfoRecord.xres = 72;
342
        m_imageInfoRecord.yres = 72;
343
        m_imageInfoRecord.BBoxX = 0;
344
        m_imageInfoRecord.colorspace = ColorSpaceRGB;
345
        m_imageInfoRecord.BBoxH = m_image.height();
346
        return true;
347
}