Subversion Repositories Scribus

Rev

Rev 16763 | Rev 16856 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 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
*/
68 Franz 7
 
6733 avox 8
#include "scpainter.h"
10203 cbradney 9
#include "util_color.h"
10988 fschmid 10
#include "util.h"
14284 fschmid 11
#include "util_math.h"
6733 avox 12
 
16281 jghali 13
#include <cairo.h>
68 Franz 14
 
15
#include <math.h>
16732 fschmid 16
#include <QDebug>
68 Franz 17
 
9319 fschmid 18
ScPainter::ScPainter( QImage *target, unsigned int w, unsigned int h, double transparency, int blendmode )
1815 fschmid 19
{
20
        m_width = w;
21
        m_height= h;
22
        m_stroke = QColor(0,0,0);
14168 fschmid 23
        strokeMode = 0;
14298 fschmid 24
        maskMode = 0;
1815 fschmid 25
        m_fill = QColor(0,0,0);
26
        fill_trans = 1.0;
27
        stroke_trans = 1.0;
28
        m_fillRule = true;
29
        fillMode = 1;
30
        LineWidth = 1.0;
31
        m_offset = 0;
9319 fschmid 32
        m_layerTransparency = transparency;
33
        m_blendMode = blendmode;
14308 fschmid 34
        m_blendModeFill = 0;
35
        m_blendModeStroke = 0;
1815 fschmid 36
        m_array.clear();
37
        mf_underline = false;
38
        mf_strikeout = false;
39
        mf_shadow = false;
40
        mf_outlined = false;
9319 fschmid 41
        PLineEnd = Qt::FlatCap;
42
        PLineJoin = Qt::MiterJoin;
1815 fschmid 43
        fill_gradient = VGradient(VGradient::linear);
44
        stroke_gradient = VGradient(VGradient::linear);
45
        m_zoomFactor = 1;
9319 fschmid 46
        layeredMode = true;
1815 fschmid 47
        imageMode = true;
9319 fschmid 48
        svgMode = false;
1815 fschmid 49
        m_image = target;
13951 fschmid 50
        m_matrix = QTransform();
9319 fschmid 51
        cairo_surface_t *img = cairo_image_surface_create_for_data(m_image->bits(), CAIRO_FORMAT_ARGB32, w, h, w*4);
3376 fschmid 52
        m_cr = cairo_create(img);
53
        cairo_save( m_cr );
54
        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
55
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
56
        cairo_set_tolerance( m_cr, 0.5 );
1815 fschmid 57
}
58
 
68 Franz 59
ScPainter::~ScPainter()
60
{
4447 fschmid 61
        cairo_surface_destroy(cairo_get_target(m_cr));
3113 fschmid 62
        cairo_destroy( m_cr );
68 Franz 63
}
64
 
7049 fschmid 65
void ScPainter::beginLayer(double transparency, int blendmode, FPointArray *clipArray)
5373 fschmid 66
{
5604 fschmid 67
        layerProp la;
68
        la.blendmode = m_blendMode;
69
        la.tranparency = m_layerTransparency;
5373 fschmid 70
        m_layerTransparency = transparency;
71
        m_blendMode = blendmode;
7049 fschmid 72
        la.pushed = false;
73
        la.groupClip.resize(0);
14854 fschmid 74
        la.maskMode = maskMode;
75
        la.mask_patternScaleX = mask_patternScaleX;
76
        la.mask_patternScaleY = mask_patternScaleY;
77
        la.mask_patternOffsetX = mask_patternOffsetX;
78
        la.mask_patternOffsetY = mask_patternOffsetY;
79
        la.mask_patternRotation = mask_patternRotation;
80
        la.mask_patternSkewX = mask_patternSkewX;
81
        la.mask_patternSkewY = mask_patternSkewY;
82
        la.mask_patternMirrorX = mask_patternMirrorX;
83
        la.mask_patternMirrorY = mask_patternMirrorY;
84
        la.mask_gradientScale = mask_gradientScale;
85
        la.mask_gradientSkew = mask_gradientSkew;
86
        la.mask_gradient = mask_gradient;
87
        la.maskPattern = m_maskPattern;
7049 fschmid 88
        if (clipArray != NULL)
89
                la.groupClip = *clipArray;
9319 fschmid 90
        la.data = cairo_get_group_target(m_cr);
16744 fschmid 91
        la.fillRule = m_fillRule;
11412 fschmid 92
        cairo_push_group(m_cr);
11424 fschmid 93
/*      if (clipArray != NULL)
9362 fschmid 94
        {
95
                setupPolygon(clipArray);
96
                setClipPath();
11424 fschmid 97
        } */
9319 fschmid 98
        la.pushed = true;
99
        Layers.push(la);
5373 fschmid 100
}
101
 
14306 fschmid 102
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
7049 fschmid 103
void ScPainter::endLayer()
5373 fschmid 104
{
7049 fschmid 105
        layerProp la;
9099 fschmid 106
        if (Layers.count() == 0)
107
                return;
14306 fschmid 108
        la = Layers.pop();
14854 fschmid 109
        maskMode = la.maskMode;
110
        mask_patternScaleX = la.mask_patternScaleX;
111
        mask_patternScaleY = la.mask_patternScaleY;
112
        mask_patternOffsetX = la.mask_patternOffsetX;
113
        mask_patternOffsetY = la.mask_patternOffsetY;
114
        mask_patternRotation = la.mask_patternRotation;
115
        mask_patternSkewX = la.mask_patternSkewX;
116
        mask_patternSkewY = la.mask_patternSkewY;
117
        mask_patternMirrorX = la.mask_patternMirrorX;
118
        mask_patternMirrorY = la.mask_patternMirrorY;
119
        mask_gradientScale = la.mask_gradientScale;
120
        mask_gradientSkew = la.mask_gradientSkew;
121
        mask_gradient = la.mask_gradient;
122
        m_maskPattern = la.maskPattern;
16744 fschmid 123
        m_fillRule = la.fillRule;
14306 fschmid 124
        if (la.pushed)
125
        {
126
                cairo_pop_group_to_source (m_cr);
127
                if (la.groupClip.size() != 0)
128
                {
16744 fschmid 129
                        if( m_fillRule )
130
                                cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
131
                        else
132
                                cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_WINDING);
14306 fschmid 133
                        setupPolygon(&la.groupClip);
134
                        setClipPath();
135
                }
14308 fschmid 136
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
137
                if (maskMode > 0)
14306 fschmid 138
                {
139
                        cairo_pattern_t *patM = getMaskPattern();
14308 fschmid 140
                        setRasterOp(m_blendMode);
14306 fschmid 141
                        cairo_mask(m_cr, patM);
16732 fschmid 142
                        if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
14318 fschmid 143
                                cairo_surface_destroy(imageMask);
14306 fschmid 144
                        cairo_pattern_destroy(patM);
145
                }
146
                else
14308 fschmid 147
                {
148
                        setRasterOp(m_blendMode);
14306 fschmid 149
                        cairo_paint_with_alpha (m_cr, m_layerTransparency);
14308 fschmid 150
                }
14306 fschmid 151
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
152
        }
153
        m_layerTransparency = la.tranparency;
154
        m_blendMode = la.blendmode;
14854 fschmid 155
        maskMode = 0;
14306 fschmid 156
}
157
#else
158
void ScPainter::endLayer()
159
{
160
        layerProp la;
161
        if (Layers.count() == 0)
162
                return;
7049 fschmid 163
        la = Layers.top();
14854 fschmid 164
        maskMode = la.maskMode;
165
        mask_patternScaleX = la.mask_patternScaleX;
166
        mask_patternScaleY = la.mask_patternScaleY;
167
        mask_patternOffsetX = la.mask_patternOffsetX;
168
        mask_patternOffsetY = la.mask_patternOffsetY;
169
        mask_patternRotation = la.mask_patternRotation;
170
        mask_patternSkewX = la.mask_patternSkewX;
171
        mask_patternSkewY = la.mask_patternSkewY;
172
        mask_patternMirrorX = la.mask_patternMirrorX;
173
        mask_patternMirrorY = la.mask_patternMirrorY;
174
        mask_gradientScale = la.mask_gradientScale;
175
        mask_gradientSkew = la.mask_gradientSkew;
176
        mask_gradient = la.mask_gradient;
177
        m_maskPattern = la.maskPattern;
16744 fschmid 178
        m_fillRule = la.fillRule;
7049 fschmid 179
        if (la.pushed)
180
        {
9315 fschmid 181
                if ((m_blendMode != 0) && (Layers.count() != 0))
5601 fschmid 182
                {
7077 fschmid 183
                        cairo_surface_t *tmp = cairo_get_group_target(m_cr);
184
                        cairo_surface_t *tmpB = Layers.top().data;
185
                        if ((tmp != NULL) && (tmpB != NULL))
5601 fschmid 186
                        {
7077 fschmid 187
                                if ((cairo_surface_get_type(tmp) == CAIRO_SURFACE_TYPE_IMAGE) && (cairo_surface_get_type(tmpB) == CAIRO_SURFACE_TYPE_IMAGE))
5601 fschmid 188
                                {
7077 fschmid 189
                                        cairo_surface_flush(tmp);
190
                                        int stride = cairo_image_surface_get_stride(tmp);
191
                                        unsigned char *s = cairo_image_surface_get_data(tmp);
192
                                        unsigned char *d = cairo_image_surface_get_data(tmpB);
193
                                        int h = cairo_image_surface_get_height(tmp);
194
                                        int w = cairo_image_surface_get_width(tmp);
195
                                        uint oldDst = 1;
196
                                        uint oldSrc = 2;
197
                                        uint newResult = 0;
198
                                        bool first = true;
7175 fschmid 199
                                        QRgb *src;
200
                                        QRgb *dst;
201
                                        uchar src_a, src_r, src_g, src_b, dst_a, dst_r, dst_g, dst_b, new_r, new_g, new_b;
7077 fschmid 202
                                        for( int yi=0; yi < h; ++yi )
5601 fschmid 203
                                        {
7175 fschmid 204
                                                dst = (QRgb*)d;
205
                                                src = (QRgb*)s;
7077 fschmid 206
                                                for( int xi=0; xi < w; ++xi )
5601 fschmid 207
                                                {
7175 fschmid 208
                                                        src_r = qRed(*src);
209
                                                        src_g = qGreen(*src);
210
                                                        src_b = qBlue(*src);
211
                                                        src_a = qAlpha(*src);
212
                                                        dst_r = qRed(*dst);
213
                                                        dst_g = qGreen(*dst);
214
                                                        dst_b = qBlue(*dst);
215
                                                        dst_a = qAlpha(*dst);
7077 fschmid 216
                                                        if ((src_a > 0) && (dst_a > 0))
5601 fschmid 217
                                                        {
7077 fschmid 218
                                                                if (((*dst) != oldDst) || ((*src) != oldSrc) || (first))
6505 fschmid 219
                                                                {
7077 fschmid 220
                                                                        if (m_blendMode == 1)
221
                                                                        {
222
                                                                                src_r = dst_r  < src_r ? dst_r  : src_r;
223
                                                                                src_g = dst_g < src_g ? dst_g : src_g;
224
                                                                                src_b = dst_b < src_b ? dst_b : src_b;
225
                                                                        }
226
                                                                        else if (m_blendMode == 2)
227
                                                                        {
228
                                                                                src_r = dst_r  < src_r ? src_r : dst_r;
229
                                                                                src_g = dst_g < src_g ? src_g : dst_g;
230
                                                                                src_b = dst_b < src_b ? src_b : dst_b;
231
                                                                        }
232
                                                                        else if (m_blendMode == 3)
233
                                                                        {
234
                                                                                src_r = INT_MULT(src_r, dst_r);
235
                                                                                src_g = INT_MULT(src_g, dst_g);
236
                                                                                src_b = INT_MULT(src_b, dst_b);
237
                                                                        }
238
                                                                        else if (m_blendMode == 4)
239
                                                                        {
12684 jghali 240
                                                                                src_r = 255 - ((255-src_r) * (255-dst_r) / 255);
241
                                                                                src_g = 255 - ((255-src_g) * (255-dst_g) / 255);
242
                                                                                src_b = 255 - ((255-src_b) * (255-dst_b) / 255);
7077 fschmid 243
                                                                        }
244
                                                                        else if (m_blendMode == 5)
245
                                                                        {
246
                                                                                src_r = dst_r < 128 ? src_r * dst_r / 128 : 255 - ((255-src_r) * (255-dst_r) / 128);
247
                                                                                src_g = dst_g < 128 ? src_g * dst_g / 128 : 255 - ((255-src_g) * (255-dst_g) / 128);
248
                                                                                src_b = dst_b < 128 ? src_b * dst_b / 128 : 255 - ((255-src_b) * (255-dst_b) / 128);
249
                                                                        }
250
                                                                        else if (m_blendMode == 6)
251
                                                                        {
252
                                                                                src_r = src_r < 128 ? src_r * dst_r / 128 : 255 - ((255-src_r) * (255-dst_r) / 128);
253
                                                                                src_g = src_g < 128 ? src_g * dst_g / 128 : 255 - ((255-src_g) * (255-dst_g) / 128);
254
                                                                                src_b = src_b < 128 ? src_b * dst_b / 128 : 255 - ((255-src_b) * (255-dst_b) / 128);
255
                                                                        }
256
                                                                        else if (m_blendMode == 7)
257
                                                                        {
258
                                                                                float s_r = (255 - src_r) / 255.0;
259
                                                                                float s_g = (255 - src_g) / 255.0;
260
                                                                                float s_b = (255 - src_b) / 255.0;
261
                                                                                float d_r = (255 - dst_r) / 255.0;
262
                                                                                float d_g = (255 - dst_g) / 255.0;
263
                                                                                float d_b = (255 - dst_b) / 255.0;
264
                                                                                float dzr = d_r > 0.25 ? sqrt(d_r) : ((16 * d_r - 12) * d_r + 4) * d_r;
265
                                                                                float dzg = d_g > 0.25 ? sqrt(d_g) : ((16 * d_g - 12) * d_g + 4) * d_g;
266
                                                                                float dzb = d_b > 0.25 ? sqrt(d_b) : ((16 * d_b - 12) * d_b + 4) * d_b;
267
                                                                                s_r = s_r <= 0.5 ? d_r - (1 - 2 * s_r) * d_r * (1 - d_r) : d_r + (2 * s_r - 1) * (dzr  - d_r);
268
                                                                                s_g = s_g <= 0.5 ? d_g - (1 - 2 * s_g) * d_g * (1 - d_g) : d_g + (2 * s_g - 1) * (dzg  - d_g);
269
                                                                                s_b = s_b <= 0.5 ? d_b - (1 - 2 * s_b) * d_b * (1 - d_b) : d_b + (2 * s_b - 1) * (dzb  - d_b);
270
                                                                                src_r = 255 - qRound(s_r * 255);
271
                                                                                src_g = 255 - qRound(s_g * 255);
272
                                                                                src_b = 255 - qRound(s_b * 255);
273
                                                                        }
274
                                                                        else if (m_blendMode == 8)
275
                                                                        {
276
                                                                                src_r = dst_r > src_r ? dst_r - src_r : src_r - dst_r;
277
                                                                                src_g = dst_g > src_g ? dst_g - src_g : src_g - dst_g;
278
                                                                                src_b = dst_b > src_b ? dst_b - src_b : src_b - dst_b;
279
                                                                        }
280
                                                                        else if (m_blendMode == 9)
281
                                                                        {
282
                                                                                src_r = dst_r + src_r - src_r * dst_r / 128;
283
                                                                                src_g = dst_g + src_g - src_g * dst_g / 128;
284
                                                                                src_b = dst_b + src_b - src_b * dst_b / 128;
285
                                                                        }
286
                                                                        else if (m_blendMode == 10)
287
                                                                        {
8562 jghali 288
                                                                                src_r = src_r == 255 ? qMin(255, dst_r * 256) : qMin(255, ((dst_r * 256) / (255-src_r)));
289
                                                                                src_g = src_g == 255 ? qMin(255, dst_g * 256) : qMin(255, ((dst_g * 256) / (255-src_g)));
290
                                                                                src_b = src_b == 255 ? qMin(255, dst_b * 256) : qMin(255, ((dst_b * 256) / (255-src_b)));
7077 fschmid 291
                                                                        }
292
                                                                        else if (m_blendMode == 11)
293
                                                                        {
8577 jghali 294
                                                                                src_r = qMax<uchar>(1, src_r);
295
                                                                                src_g = qMax<uchar>(1, src_g);
296
                                                                                src_b = qMax<uchar>(1, src_b);
7077 fschmid 297
                                                                                src_r = static_cast<int>(255 - (((255-dst_r) * 256) / src_r)) < 0 ? 0 : 255 - (((255-dst_r) * 256) / src_r);
298
                                                                                src_g = static_cast<int>(255 - (((255-dst_g) * 256) / src_g)) < 0 ? 0 : 255 - (((255-dst_g) * 256) / src_g);
299
                                                                                src_b = static_cast<int>(255 - (((255-dst_b) * 256) / src_b)) < 0 ? 0 : 255 - (((255-dst_b) * 256) / src_b);
300
                                                                        }
301
                                                                        else if (m_blendMode == 12)
302
                                                                        {
7175 fschmid 303
                                                                                new_r = dst_r;
304
                                                                                new_g = dst_g;
305
                                                                                new_b = dst_b;
8027 fschmid 306
                                                                                RGBTOHLS(src_r, src_g, src_b);
307
                                                                                RGBTOHLS(new_r, new_g, new_b);
308
                                                                                new_r = src_r;
309
                                                                                HLSTORGB(new_r, new_g, new_b);
7077 fschmid 310
                                                                                src_r = new_r;
311
                                                                                src_g = new_g;
312
                                                                                src_b = new_b;
313
                                                                        }
314
                                                                        else if (m_blendMode == 13)
315
                                                                        {
7175 fschmid 316
                                                                                new_r = dst_r;
317
                                                                                new_g = dst_g;
318
                                                                                new_b = dst_b;
8027 fschmid 319
                                                                                RGBTOHLS(src_r, src_g, src_b);
320
                                                                                RGBTOHLS(new_r, new_g, new_b);
321
                                                                                new_b = src_b;
322
                                                                                HLSTORGB(new_r, new_g, new_b);
7077 fschmid 323
                                                                                src_r = new_r;
324
                                                                                src_g = new_g;
325
                                                                                src_b = new_b;
326
                                                                        }
327
                                                                        else if (m_blendMode == 14)
328
                                                                        {
8019 fschmid 329
                                                                                new_r = src_r;
330
                                                                                new_g = src_g;
331
                                                                                new_b = src_b;
332
                                                                                setLum(new_r, new_g, new_b, Lum(dst_r, dst_g, dst_b));
7077 fschmid 333
                                                                                src_r = new_r;
334
                                                                                src_g = new_g;
335
                                                                                src_b = new_b;
336
                                                                        }
337
                                                                        else if (m_blendMode == 15)
338
                                                                        {
7175 fschmid 339
                                                                                new_r = dst_r;
340
                                                                                new_g = dst_g;
341
                                                                                new_b = dst_b;
8018 fschmid 342
                                                                                setLum(new_r, new_g, new_b, Lum(src_r, src_g, src_b));
7077 fschmid 343
                                                                                src_r = new_r;
344
                                                                                src_g = new_g;
345
                                                                                src_b = new_b;
346
                                                                        }
347
                                                                        newResult = qRgba(src_r, src_g, src_b, src_a);
348
                                                                        oldDst = (*dst);
349
                                                                        oldSrc = (*src);
350
                                                                        first = false;
6505 fschmid 351
                                                                }
7077 fschmid 352
                                                                (*src) = newResult;
5601 fschmid 353
                                                        }
7077 fschmid 354
                                                        src++;
355
                                                        dst++;
5601 fschmid 356
                                                }
7077 fschmid 357
                                                s += stride;
358
                                                d += stride;
5601 fschmid 359
                                        }
7077 fschmid 360
                                        cairo_surface_mark_dirty(tmp);
5601 fschmid 361
                                }
362
                        }
12644 fschmid 363
                }
14306 fschmid 364
        }
365
        la = Layers.pop();
366
        if (la.pushed)
367
        {
368
                cairo_pop_group_to_source (m_cr);
369
                if (la.groupClip.size() != 0)
370
                {
16744 fschmid 371
                        if( m_fillRule )
372
                                cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
373
                        else
374
                                cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_WINDING);
14306 fschmid 375
                        setupPolygon(&la.groupClip);
376
                        setClipPath();
377
                }
378
                if (m_blendMode == 0)
379
                {
380
                        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
381
                        if (maskMode == 1)
382
                        {
383
                                cairo_pattern_t *patM = getMaskPattern();
384
                                cairo_mask(m_cr, patM);
16732 fschmid 385
                                if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
14318 fschmid 386
                                        cairo_surface_destroy(imageMask);
14306 fschmid 387
                                cairo_pattern_destroy(patM);
388
                        }
389
                        else
390
                                cairo_paint_with_alpha (m_cr, m_layerTransparency);
391
                }
392
                else
393
                {
394
                        if (maskMode == 1)
395
                        {
396
                                cairo_pattern_t *patM = getMaskPattern();
397
                                cairo_mask(m_cr, patM);
16732 fschmid 398
                                if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
14318 fschmid 399
                                        cairo_surface_destroy(imageMask);
14306 fschmid 400
                                cairo_pattern_destroy(patM);
401
                        }
402
                        else
403
                        {
404
                                cairo_set_operator(m_cr, CAIRO_OPERATOR_DEST_OUT);
405
                                cairo_paint_with_alpha (m_cr, m_layerTransparency);
406
                                cairo_set_operator(m_cr, CAIRO_OPERATOR_ADD);
407
                                cairo_paint_with_alpha (m_cr, m_layerTransparency);
408
                        }
409
                }
410
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
411
        }
412
        m_layerTransparency = la.tranparency;
413
        m_blendMode = la.blendmode;
14854 fschmid 414
        maskMode = 0;
14306 fschmid 415
}
416
#endif
5373 fschmid 417
 
68 Franz 418
void ScPainter::begin()
419
{
420
}
421
 
422
void ScPainter::end()
423
{
5471 fschmid 424
        if (svgMode)
425
                cairo_show_page (m_cr);
5373 fschmid 426
        if (layeredMode)
427
        {
5433 fschmid 428
                cairo_surface_flush(cairo_get_target(m_cr));
5373 fschmid 429
                cairo_restore( m_cr );
430
                return;
431
        }
68 Franz 432
}
433
 
1624 fschmid 434
void ScPainter::clear()
68 Franz 435
{
3376 fschmid 436
        if (imageMode)
437
                m_image->fill( qRgba(255, 255, 255, 255) );
68 Franz 438
}
439
 
1624 fschmid 440
void ScPainter::clear( const QColor &c )
68 Franz 441
{
9319 fschmid 442
        QRgb cs = c.rgb();
3376 fschmid 443
        if (imageMode)
444
                m_image->fill( qRgba(qRed(cs), qGreen(cs), qBlue(cs), qAlpha(cs)) );
68 Franz 445
}
446
 
13951 fschmid 447
const QTransform ScPainter::worldMatrix()
3113 fschmid 448
{
449
        cairo_matrix_t matrix;
450
        cairo_get_matrix(m_cr, &matrix);
13951 fschmid 451
        QTransform mat = QTransform( matrix.xx, matrix.yx, matrix.xy, matrix.yy, matrix.x0, matrix.y0 );
3113 fschmid 452
        return mat;
453
}
454
 
13951 fschmid 455
void ScPainter::setWorldMatrix( const QTransform &mat )
68 Franz 456
{
3113 fschmid 457
        cairo_matrix_t matrix;
458
        cairo_matrix_init(&matrix, mat.m11(), mat.m12(), mat.m21(), mat.m22(), mat.dx(), mat.dy());
459
        cairo_set_matrix(m_cr, &matrix);
68 Franz 460
}
461
 
6809 fschmid 462
void ScPainter::setAntialiasing(bool enable)
463
{
464
        if (enable)
465
                cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_DEFAULT);
466
        else
467
                cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_NONE);
468
}
469
 
68 Franz 470
void ScPainter::setZoomFactor( double zoomFactor )
471
{
472
        m_zoomFactor = zoomFactor;
11196 fschmid 473
        cairo_scale (m_cr, m_zoomFactor, m_zoomFactor);
68 Franz 474
}
475
 
476
void ScPainter::translate( double x, double y )
477
{
3113 fschmid 478
        cairo_translate (m_cr, x, y);
68 Franz 479
}
480
 
481
void ScPainter::rotate( double r )
482
{
3113 fschmid 483
        cairo_rotate (m_cr, r * 3.1415927 / 180.0);
68 Franz 484
}
485
 
486
void ScPainter::scale( double x, double y )
487
{
3113 fschmid 488
        cairo_scale (m_cr, x, y);
68 Franz 489
}
490
 
491
void ScPainter::moveTo( const double &x, const double &y )
492
{
11196 fschmid 493
        cairo_move_to( m_cr, x, y);
68 Franz 494
}
495
 
4646 subik 496
void
68 Franz 497
ScPainter::lineTo( const double &x, const double &y )
498
{
11196 fschmid 499
        cairo_line_to( m_cr, x, y);
68 Franz 500
}
501
 
502
void ScPainter::curveTo( FPoint p1, FPoint p2, FPoint p3 )
503
{
11196 fschmid 504
        cairo_curve_to(m_cr, p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y());
68 Franz 505
}
506
 
507
void ScPainter::newPath()
508
{
3113 fschmid 509
        cairo_new_path( m_cr );
68 Franz 510
}
511
 
5233 fschmid 512
void ScPainter::closePath()
513
{
514
        cairo_close_path( m_cr );
515
}
516
 
68 Franz 517
void ScPainter::setFillRule( bool fillRule )
518
{
519
        m_fillRule = fillRule;
520
}
521
 
522
void ScPainter::setFillMode( int fill )
523
{
524
        fillMode = fill;
525
}
526
 
14168 fschmid 527
void ScPainter::setStrokeMode( int stroke )
528
{
529
        strokeMode = stroke;
530
}
531
 
14284 fschmid 532
void ScPainter::setGradient(VGradient::VGradientType mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew)
68 Franz 533
{
534
        fill_gradient.setType(mode);
535
        fill_gradient.setOrigin(orig);
536
        fill_gradient.setVector(vec);
537
        fill_gradient.setFocalPoint(foc);
14168 fschmid 538
        stroke_gradient.setType(mode);
539
        stroke_gradient.setOrigin(orig);
540
        stroke_gradient.setVector(vec);
541
        stroke_gradient.setFocalPoint(foc);
14284 fschmid 542
        gradientScale = scale;
543
        if (skew == 90)
544
                gradientSkew = 1;
545
        else if (skew == 180)
546
                gradientSkew = 0;
547
        else if (skew == 270)
548
                gradientSkew = -1;
14382 fschmid 549
        else if (skew == 360)
14284 fschmid 550
                gradientSkew = 0;
551
        else
552
                gradientSkew = tan(M_PI / 180.0 * skew);
68 Franz 553
}
554
 
14297 fschmid 555
void ScPainter::setMaskMode(int mask)
556
{
557
        maskMode = mask;
558
}
559
 
560
void ScPainter::setGradientMask(VGradient::VGradientType mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew)
561
{
562
        mask_gradient.setType(mode);
563
        mask_gradient.setOrigin(orig);
564
        mask_gradient.setVector(vec);
565
        mask_gradient.setFocalPoint(foc);
566
        mask_gradientScale = scale;
567
        if (skew == 90)
568
                mask_gradientSkew = 1;
569
        else if (skew == 180)
570
                mask_gradientSkew = 0;
571
        else if (skew == 270)
572
                mask_gradientSkew = -1;
14382 fschmid 573
        else if (skew == 360)
14297 fschmid 574
                mask_gradientSkew = 0;
575
        else
576
                mask_gradientSkew = tan(M_PI / 180.0 * skew);
577
}
578
 
579
void ScPainter::setPatternMask(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
580
{
581
        m_maskPattern = pattern;
582
        mask_patternScaleX = scaleX / 100.0;
583
        mask_patternScaleY = scaleY / 100.0;
584
        mask_patternOffsetX = offsetX;
585
        mask_patternOffsetY = offsetY;
586
        mask_patternRotation = rotation;
587
        mask_patternSkewX = skewX;
588
        mask_patternSkewY = skewY;
589
        mask_patternMirrorX = mirrorX;
590
        mask_patternMirrorY = mirrorY;
591
}
592
 
14952 fschmid 593
void ScPainter::set4ColorGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4)
594
{
595
        fill_gradient.setType(VGradient::fourcolor);
596
        gradPatchP1 = p1;
597
        gradPatchP2 = p2;
598
        gradPatchP3 = p3;
599
        gradPatchP4 = p4;
600
        gradControlP1 = c1;
601
        gradControlP2 = c2;
602
        gradControlP3 = c3;
603
        gradControlP4 = c4;
604
}
605
 
606
void ScPainter::set4ColorColors(QColor col1, QColor col2, QColor col3, QColor col4)
607
{
608
        gradPatchColor1 = col1;
609
        gradPatchColor2 = col2;
610
        gradPatchColor3 = col3;
611
        gradPatchColor4 = col4;
612
}
613
 
14981 fschmid 614
void ScPainter::setDiamondGeometry(FPoint p1, FPoint p2, FPoint p3, FPoint p4, FPoint c1, FPoint c2, FPoint c3, FPoint c4, FPoint c5)
615
{
616
        fill_gradient.setType(VGradient::diamond);
617
        gradPatchP1 = p1;
618
        gradPatchP2 = p2;
619
        gradPatchP3 = p3;
620
        gradPatchP4 = p4;
621
        gradControlP1 = c1;
622
        gradControlP2 = c2;
623
        gradControlP3 = c3;
624
        gradControlP4 = c4;
625
        gradControlP5 = c5;
626
}
627
 
15024 fschmid 628
void ScPainter::setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<QList<meshPoint> > meshArray)
629
{
630
        fill_gradient.setType(VGradient::mesh);
631
        meshGradientArray = meshArray;
632
        gradPatchP1 = p1;
633
        gradPatchP2 = p2;
634
        gradPatchP3 = p3;
635
        gradPatchP4 = p4;
636
}
637
 
16729 fschmid 638
void ScPainter::setMeshGradient(FPoint p1, FPoint p2, FPoint p3, FPoint p4, QList<meshGradientPatch> meshPatches)
639
{
640
        fill_gradient.setType(VGradient::freemesh);
641
        meshGradientPatches = meshPatches;
642
        gradPatchP1 = p1;
643
        gradPatchP2 = p2;
644
        gradPatchP3 = p3;
645
        gradPatchP4 = p4;
646
}
647
 
1998 fschmid 648
void ScPainter::fillTextPath()
649
{
3113 fschmid 650
        drawVPath( 0 );
1998 fschmid 651
}
652
 
653
void ScPainter::strokeTextPath()
654
{
13013 fschmid 655
//      if( LineWidth == 0 )
656
//              return;
3113 fschmid 657
        drawVPath( 1 );
1998 fschmid 658
}
659
 
68 Franz 660
void ScPainter::fillPath()
661
{
3113 fschmid 662
        if( fillMode != 0)
663
                drawVPath( 0 );
68 Franz 664
}
665
 
666
void ScPainter::strokePath()
667
{
13013 fschmid 668
//      if( LineWidth == 0 )
669
//              return;
3113 fschmid 670
        drawVPath( 1 );
68 Franz 671
}
672
 
673
QColor ScPainter::pen()
674
{
675
        return m_stroke;
676
}
677
 
678
QColor ScPainter::brush()
679
{
680
        return m_fill;
681
}
682
 
683
void ScPainter::setPen( const QColor &c )
684
{
685
        m_stroke = c;
686
}
687
 
80 Franz 688
void ScPainter::setPen( const QColor &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
68 Franz 689
{
690
        m_stroke = c;
691
        LineWidth = w;
692
        PLineEnd = ca;
693
        PLineJoin = jo;
10988 fschmid 694
        m_offset = 0;
695
        getDashArray(st, w, m_array);
68 Franz 696
}
697
 
80 Franz 698
void ScPainter::setLineWidth( double w )
68 Franz 699
{
700
        LineWidth = w;
701
}
702
 
80 Franz 703
void ScPainter::setPenOpacity( double op )
68 Franz 704
{
705
        stroke_trans = op;
706
}
707
 
708
 
12055 jghali 709
void ScPainter::setDash(const QVector<double>& array, double ofs)
68 Franz 710
{
711
        m_array = array;
712
        m_offset = ofs;
713
}
714
 
715
void ScPainter::setBrush( const QColor &c )
716
{
717
        m_fill = c;
718
}
719
 
80 Franz 720
void ScPainter::setBrushOpacity( double op )
68 Franz 721
{
722
        fill_trans = op;
723
}
724
 
80 Franz 725
void ScPainter::setOpacity( double op )
68 Franz 726
{
727
        fill_trans = op;
728
        stroke_trans = op;
729
}
730
 
731
void ScPainter::setFont( const QFont &f)
732
{
733
        m_font = f;
734
}
735
 
736
QFont ScPainter::font()
737
{
738
        return m_font;
739
}
740
 
741
void ScPainter::save()
742
{
3113 fschmid 743
        cairo_save( m_cr );
68 Franz 744
}
745
 
746
void ScPainter::restore()
747
{
3113 fschmid 748
        cairo_restore( m_cr );
68 Franz 749
}
750
 
14306 fschmid 751
void ScPainter::setRasterOp(int blendMode)
68 Franz 752
{
14306 fschmid 753
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
754
        if (blendMode == 0)
755
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
756
        else if (blendMode == 1)
757
                cairo_set_operator(m_cr, CAIRO_OPERATOR_DARKEN);
758
        else if (blendMode == 2)
759
                cairo_set_operator(m_cr, CAIRO_OPERATOR_LIGHTEN);
760
        else if (blendMode == 3)
761
                cairo_set_operator(m_cr, CAIRO_OPERATOR_MULTIPLY);
762
        else if (blendMode == 4)
763
                cairo_set_operator(m_cr, CAIRO_OPERATOR_SCREEN);
764
        else if (blendMode == 5)
765
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVERLAY);
766
        else if (blendMode == 6)
767
                cairo_set_operator(m_cr, CAIRO_OPERATOR_HARD_LIGHT);
768
        else if (blendMode == 7)
769
                cairo_set_operator(m_cr, CAIRO_OPERATOR_SOFT_LIGHT);
770
        else if (blendMode == 8)
771
                cairo_set_operator(m_cr, CAIRO_OPERATOR_DIFFERENCE);
772
        else if (blendMode == 9)
773
                cairo_set_operator(m_cr, CAIRO_OPERATOR_EXCLUSION);
774
        else if (blendMode == 10)
775
                cairo_set_operator(m_cr, CAIRO_OPERATOR_COLOR_DODGE);
776
        else if (blendMode == 11)
777
                cairo_set_operator(m_cr, CAIRO_OPERATOR_COLOR_BURN);
778
        else if (blendMode == 12)
779
                cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_HUE);
780
        else if (blendMode == 13)
781
                cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_SATURATION);
782
        else if (blendMode == 14)
783
                cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_COLOR);
784
        else if (blendMode == 15)
785
                cairo_set_operator(m_cr, CAIRO_OPERATOR_HSL_LUMINOSITY);
14308 fschmid 786
        else
787
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
14306 fschmid 788
#endif
68 Franz 789
}
790
 
14306 fschmid 791
void ScPainter::setBlendModeFill( int blendMode )
792
{
793
        m_blendModeFill = blendMode;
794
}
795
 
796
void ScPainter::setBlendModeStroke( int blendMode )
797
{
798
        m_blendModeStroke = blendMode;
799
}
800
 
14276 fschmid 801
void ScPainter::setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
6368 fschmid 802
{
6369 fschmid 803
        m_pattern = pattern;
6414 fschmid 804
        patternScaleX = scaleX / 100.0;
805
        patternScaleY = scaleY / 100.0;
806
        patternOffsetX = offsetX;
807
        patternOffsetY = offsetY;
808
        patternRotation = rotation;
14260 fschmid 809
        patternSkewX = skewX;
810
        patternSkewY = skewY;
14276 fschmid 811
        patternMirrorX = mirrorX;
812
        patternMirrorY = mirrorY;
6368 fschmid 813
}
814
 
14298 fschmid 815
cairo_pattern_t * ScPainter::getMaskPattern()
816
{
14308 fschmid 817
        cairo_save( m_cr );
14298 fschmid 818
        cairo_pattern_t *pat;
14318 fschmid 819
        if ((maskMode == 1) || (maskMode == 3))
14298 fschmid 820
        {
14308 fschmid 821
                double x1 = mask_gradient.origin().x();
822
                double y1 = mask_gradient.origin().y();
823
                double x2 = mask_gradient.vector().x();
824
                double y2 = mask_gradient.vector().y();
825
                double fx = mask_gradient.focalPoint().x();
826
                double fy = mask_gradient.focalPoint().y();
827
                if (mask_gradient.type() == VGradient::linear)
828
                        pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
829
                else
830
                        pat = cairo_pattern_create_radial (fx, fy, 0, x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)));
831
                QList<VColorStop*> colorStops = mask_gradient.colorStops();
832
                QColor qStopColor;
833
                for( int offset = 0 ; offset < colorStops.count() ; offset++ )
834
                {
835
                        qStopColor = colorStops[ offset ]->color;
836
                        int h, s, v, sneu, vneu;
837
                        int shad = colorStops[offset]->shade;
838
                        qStopColor.getHsv(&h, &s, &v);
839
                        sneu = s * shad / 100;
840
                        vneu = 255 - ((255 - v) * shad / 100);
841
                        qStopColor.setHsv(h, sneu, vneu);
842
                        double a = colorStops[offset]->opacity;
843
                        double r, g, b;
844
                        qStopColor.getRgbF(&r, &g, &b);
14318 fschmid 845
                        if (maskMode == 3)
14825 fschmid 846
                                a = /* 1.0 - */(0.3 * r + 0.59 * g + 0.11 * b);
14308 fschmid 847
                        cairo_pattern_add_color_stop_rgba (pat, colorStops[ offset ]->rampPoint, r, g, b, a);
848
                }
849
                cairo_matrix_t matrix;
850
                QTransform qmatrix;
851
                if (mask_gradient.type() == VGradient::radial)
852
                {
853
                        double rotEnd = xy2Deg(x2 - x1, y2 - y1);
854
                        qmatrix.translate(x1, y1);
855
                        qmatrix.rotate(rotEnd);
856
                        qmatrix.shear(mask_gradientSkew, 0);
857
                        qmatrix.translate(0, y1 * (1.0 - mask_gradientScale));
858
                        qmatrix.translate(-x1, -y1);
859
                        qmatrix.scale(1, mask_gradientScale);
860
                }
861
                else
862
                {
863
                        qmatrix.translate(x1, y1);
864
                        qmatrix.shear(-mask_gradientSkew, 0);
865
                        qmatrix.translate(-x1, -y1);
866
                }
867
                cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
868
                cairo_matrix_invert(&matrix);
869
                cairo_pattern_set_matrix (pat, &matrix);
14298 fschmid 870
        }
871
        else
872
        {
16732 fschmid 873
                if ((maskMode == 4) || (maskMode == 5))
14318 fschmid 874
                {
875
                        imageQ = m_maskPattern->pattern.copy();
16732 fschmid 876
                        if (maskMode == 5)
877
                                imageQ.invertPixels();
14318 fschmid 878
                        int h = imageQ.height();
879
                        int w = imageQ.width();
880
                        int k;
881
                        QRgb *s;
882
                        QRgb r;
883
                        for( int yi=0; yi < h; ++yi )
884
                        {
885
                                s = (QRgb*)(imageQ.scanLine( yi ));
886
                                for( int xi=0; xi < w; ++xi )
887
                                {
888
                                        r = *s;
889
                                        if (qAlpha(r) == 0)
14825 fschmid 890
                                                k = 0; // 255;
14318 fschmid 891
                                        else
892
                                                k = qMin(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
14825 fschmid 893
                                        *s = qRgba(qRed(r), qGreen(r), qBlue(r), /* 255 - */ k);
14318 fschmid 894
                                        s++;
895
                                }
896
                        }
897
                        imageMask = cairo_image_surface_create_for_data ((uchar*)imageQ.bits(), CAIRO_FORMAT_ARGB32, w, h, w*4);
898
                }
899
                else
16732 fschmid 900
                {
901
                        imageQ = m_maskPattern->pattern.copy();
902
                        if (maskMode == 6)
903
                                imageQ.invertPixels(QImage::InvertRgba);
904
                        imageMask = cairo_image_surface_create_for_data ((uchar*)imageQ.bits(), CAIRO_FORMAT_ARGB32, m_maskPattern->getPattern()->width(), m_maskPattern->getPattern()->height(), m_maskPattern->getPattern()->width()*4);
905
                }
14318 fschmid 906
                pat = cairo_pattern_create_for_surface(imageMask);
14308 fschmid 907
                cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
14952 fschmid 908
                cairo_pattern_set_filter(pat, CAIRO_FILTER_GOOD);
14308 fschmid 909
                cairo_matrix_t matrix;
910
                QTransform qmatrix;
911
                qmatrix.translate(mask_patternOffsetX, mask_patternOffsetY);
912
                qmatrix.rotate(mask_patternRotation);
913
                qmatrix.shear(-mask_patternSkewX, mask_patternSkewY);
914
                qmatrix.scale(mask_patternScaleX, mask_patternScaleY);
915
                qmatrix.scale(m_maskPattern->width / static_cast<double>(m_maskPattern->getPattern()->width()), m_maskPattern->height / static_cast<double>(m_maskPattern->getPattern()->height()));
916
                if (mask_patternMirrorX)
917
                        qmatrix.scale(-1, 1);
918
                if (mask_patternMirrorY)
919
                        qmatrix.scale(1, -1);
920
                cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
921
                cairo_matrix_invert(&matrix);
922
                cairo_pattern_set_matrix (pat, &matrix);
14298 fschmid 923
        }
14308 fschmid 924
        cairo_restore( m_cr );
14298 fschmid 925
        return pat;
926
}
927
 
3113 fschmid 928
void ScPainter::drawVPath( int mode )
68 Franz 929
{
3113 fschmid 930
        cairo_save( m_cr );
14306 fschmid 931
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
3113 fschmid 932
        if (mode == 0)
933
        {
934
                if( m_fillRule )
935
                        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
936
                else
937
                        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_WINDING);
6368 fschmid 938
                if (fillMode == 1)
3113 fschmid 939
                {
10318 fschmid 940
                        double r, g, b;
941
                        m_fill.getRgbF(&r, &g, &b);
14308 fschmid 942
                        if (maskMode > 0)
14265 fschmid 943
                        {
14308 fschmid 944
                                cairo_pattern_t *pat = getMaskPattern();
14265 fschmid 945
                                cairo_set_source_rgb( m_cr, r, g, b );
14306 fschmid 946
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
947
                                setRasterOp(m_blendModeFill);
948
#endif
14308 fschmid 949
                                cairo_clip_preserve(m_cr);
14265 fschmid 950
                                cairo_mask(m_cr, pat);
16732 fschmid 951
                                if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
14318 fschmid 952
                                        cairo_surface_destroy(imageMask);
14308 fschmid 953
                                cairo_pattern_destroy(pat);
14265 fschmid 954
                        }
955
                        else
956
                        {
14297 fschmid 957
                                cairo_set_source_rgba( m_cr, r, g, b, fill_trans );
14306 fschmid 958
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
959
                                setRasterOp(m_blendModeFill);
960
#endif
14297 fschmid 961
                                cairo_fill_preserve(m_cr);
962
                        }
6368 fschmid 963
                }
964
                else if (fillMode == 2)
965
                {
15103 fschmid 966
                        cairo_pattern_t *pat = NULL;
967
                        cairo_surface_t *img = NULL;
968
                        cairo_t *cr = NULL;
16297 fschmid 969
// #ifdef HAVE_PRIVATE_CAIRO
970
#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)  || HAVE_PRIVATE_CAIRO)
15103 fschmid 971
                        cairo_pattern_t *mpat = NULL;
14952 fschmid 972
#endif
973
                        if (fill_gradient.type() == VGradient::fourcolor)
3113 fschmid 974
                        {
16297 fschmid 975
//#ifdef HAVE_PRIVATE_CAIRO
976
#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) || HAVE_PRIVATE_CAIRO)
14952 fschmid 977
                                double p1x = gradPatchP1.x();
978
                                double p1y = gradPatchP1.y();
979
                                double p2x = gradPatchP2.x();
980
                                double p2y = gradPatchP2.y();
981
                                double p3x = gradPatchP3.x();
982
                                double p3y = gradPatchP3.y();
983
                                double p4x = gradPatchP4.x();
984
                                double p4y = gradPatchP4.y();
985
                                img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
986
                                cr = cairo_create(img);
987
                                cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
988
                                cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
989
                                cairo_set_tolerance(cr, 0.5 );
990
                                double r, g, b, a;
991
                                mpat = cairo_pattern_create_mesh();
16297 fschmid 992
                                cairo_pattern_mesh_begin_patch(mpat);
993
                                cairo_pattern_mesh_move_to(mpat, p1x, p1y);
994
                                cairo_pattern_mesh_line_to(mpat, p2x, p2y);
995
                                cairo_pattern_mesh_line_to(mpat, p3x, p3y);
996
                                cairo_pattern_mesh_line_to(mpat, p4x, p4y);
997
                                cairo_pattern_mesh_line_to(mpat, p1x, p1y);
998
                                cairo_pattern_mesh_set_control_point(mpat, 0, gradControlP1.x(),  gradControlP1.y());
999
                                cairo_pattern_mesh_set_control_point(mpat, 1, gradControlP2.x(),  gradControlP2.y());
1000
                                cairo_pattern_mesh_set_control_point(mpat, 2, gradControlP3.x(),  gradControlP3.y());
1001
                                cairo_pattern_mesh_set_control_point(mpat, 3, gradControlP4.x(),  gradControlP4.y());
14952 fschmid 1002
                                gradPatchColor1.getRgbF(&r, &g, &b, &a);
16297 fschmid 1003
                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14952 fschmid 1004
                                gradPatchColor2.getRgbF(&r, &g, &b, &a);
16297 fschmid 1005
                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
14952 fschmid 1006
                                gradPatchColor3.getRgbF(&r, &g, &b, &a);
16297 fschmid 1007
                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
14952 fschmid 1008
                                gradPatchColor4.getRgbF(&r, &g, &b, &a);
16297 fschmid 1009
                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
1010
                                cairo_pattern_mesh_end_patch(mpat);
14952 fschmid 1011
                                cairo_pattern_set_filter(mpat, CAIRO_FILTER_GOOD);
1012
                                cairo_set_source(cr, mpat);
1013
                                cairo_paint_with_alpha(cr, 1.0);
1014
                                pat = cairo_pattern_create_for_surface(img);
1015
                                cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
1016
                                cairo_pattern_set_filter(pat, CAIRO_FILTER_GOOD);
1017
#else
1018
                                double r, g, b, a;
1019
                                double acr = 0.0;
1020
                                double acg = 0.0;
1021
                                double acb = 0.0;
1022
                                double aca = 0.0;
1023
                                gradPatchColor1.getRgbF(&r, &g, &b, &a);
1024
                                acr += r;
1025
                                acg += g;
1026
                                acb += b;
1027
                                aca += a;
1028
                                gradPatchColor2.getRgbF(&r, &g, &b, &a);
1029
                                acr += r;
1030
                                acg += g;
1031
                                acb += b;
1032
                                aca += a;
1033
                                gradPatchColor3.getRgbF(&r, &g, &b, &a);
1034
                                acr += r;
1035
                                acg += g;
1036
                                acb += b;
1037
                                aca += a;
1038
                                gradPatchColor4.getRgbF(&r, &g, &b, &a);
1039
                                acr += r;
1040
                                acg += g;
1041
                                acb += b;
1042
                                aca += a;
1043
                                pat = cairo_pattern_create_rgba(acr / 4.0, acg / 4.0, acb / 4.0, aca / 4.0);
1044
#endif
3113 fschmid 1045
                        }
14981 fschmid 1046
                        else if (fill_gradient.type() == VGradient::diamond)
1047
                        {
16297 fschmid 1048
// #ifdef HAVE_PRIVATE_CAIRO
1049
#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) || HAVE_PRIVATE_CAIRO)
14981 fschmid 1050
                                double p1x = gradControlP1.x();
1051
                                double p1y = gradControlP1.y();
1052
                                double p2x = gradControlP2.x();
1053
                                double p2y = gradControlP2.y();
1054
                                double p3x = gradControlP3.x();
1055
                                double p3y = gradControlP3.y();
1056
                                double p4x = gradControlP4.x();
1057
                                double p4y = gradControlP4.y();
1058
                                img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, gradPatchP3.x(), gradPatchP3.y());
1059
                                cr = cairo_create(img);
1060
                                cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
1061
                                cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1062
                                cairo_set_tolerance(cr, 0.5 );
1063
                                double r, g, b, a;
1064
                                QList<VColorStop*> colorStops = fill_gradient.colorStops();
1065
                                QList<QColor> qStopColors;
1066
                                QColor qStopColor;
1067
                                for( int offset = 0 ; offset < colorStops.count() ; offset++ )
1068
                                {
1069
                                        qStopColor = colorStops[ offset ]->color;
1070
                                        int h, s, v, sneu, vneu;
1071
                                        int shad = colorStops[offset]->shade;
1072
                                        qStopColor.getHsv(&h, &s, &v);
1073
                                        sneu = s * shad / 100;
1074
                                        vneu = 255 - ((255 - v) * shad / 100);
1075
                                        qStopColor.setHsv(h, sneu, vneu);
1076
                                        qStopColor.setAlphaF(colorStops[offset]->opacity);
1077
                                        qStopColors.append(qStopColor);
1078
                                }
14987 fschmid 1079
                                qStopColors[qStopColors.count()-1].getRgbF(&r, &g, &b, &a);
15024 fschmid 1080
                                QPointF centerP = QPointF(gradControlP5.x(), gradControlP5.y());
1081
                                QLineF edge1 = QLineF(centerP, QPointF(p1x, p1y));
1082
                                QLineF edge2 = QLineF(centerP, QPointF(p2x, p2y));
1083
                                QLineF edge3 = QLineF(centerP, QPointF(p3x, p3y));
1084
                                QLineF edge4 = QLineF(centerP, QPointF(p4x, p4y));
1085
                                QPointF p1 = edge1.pointAt(colorStops[colorStops.count()-1]->rampPoint);
1086
                                QPointF p2 = edge2.pointAt(colorStops[colorStops.count()-1]->rampPoint);
1087
                                QPointF p3 = edge3.pointAt(colorStops[colorStops.count()-1]->rampPoint);
1088
                                QPointF p4 = edge4.pointAt(colorStops[colorStops.count()-1]->rampPoint);
14987 fschmid 1089
                                cairo_set_source_rgba(cr, r, g, b, a);
1090
                                cairo_paint_with_alpha(cr, 1.0);
1091
                                cairo_set_operator(cr, CAIRO_OPERATOR_DEST_OUT);
1092
                                cairo_new_path(cr);
15024 fschmid 1093
                                cairo_move_to(cr, p1.x(), p1.y());
1094
                                cairo_line_to(cr, p2.x(), p2.y());
1095
                                cairo_line_to(cr, p3.x(), p3.y());
1096
                                cairo_line_to(cr, p4.x(), p4.y());
14987 fschmid 1097
                                cairo_close_path(cr);
1098
                                cairo_set_source_rgba(cr, 0, 0, 0, 1);
1099
                                cairo_fill(cr);
1100
                                cairo_set_operator(cr, CAIRO_OPERATOR_ADD);
14981 fschmid 1101
                                mpat = cairo_pattern_create_mesh();
1102
                                for( int offset = 1 ; offset < colorStops.count() ; offset++ )
1103
                                {
1104
                                        QLineF e1 = edge1;
1105
                                        QLineF e1s = edge1;
1106
                                        QLineF e2 = edge2;
1107
                                        QLineF e2s = edge2;
1108
                                        QLineF e3 = edge3;
1109
                                        QLineF e3s = edge3;
1110
                                        QLineF e4 = edge4;
1111
                                        QLineF e4s = edge4;
1112
                                        e1.setLength(edge1.length() * colorStops[ offset ]->rampPoint);
1113
                                        e2.setLength(edge2.length() * colorStops[ offset ]->rampPoint);
1114
                                        e3.setLength(edge3.length() * colorStops[ offset ]->rampPoint);
1115
                                        e4.setLength(edge4.length() * colorStops[ offset ]->rampPoint);
1116
                                        e1s.setLength(edge1.length() * colorStops[ offset - 1 ]->rampPoint);
1117
                                        e2s.setLength(edge2.length() * colorStops[ offset - 1 ]->rampPoint);
1118
                                        e3s.setLength(edge3.length() * colorStops[ offset - 1 ]->rampPoint);
1119
                                        e4s.setLength(edge4.length() * colorStops[ offset - 1 ]->rampPoint);
1120
                                        if (offset == 1)
1121
                                        {
16297 fschmid 1122
                                                cairo_pattern_mesh_begin_patch(mpat);
1123
                                                cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
1124
                                                cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
1125
                                                cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
1126
#ifdef HAVE_PRIVATE_CAIRO
1127
                                                cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
1128
#endif
14981 fschmid 1129
                                                qStopColors[0].getRgbF(&r, &g, &b, &a);
16297 fschmid 1130
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1131
                                                qStopColors[1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1132
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1133
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
1134
                                                cairo_pattern_mesh_end_patch(mpat);
1135
                                                cairo_pattern_mesh_begin_patch(mpat);
1136
                                                cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
1137
                                                cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
1138
                                                cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
1139
#ifdef HAVE_PRIVATE_CAIRO
1140
                                                cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
1141
#endif
14981 fschmid 1142
                                                qStopColors[0].getRgbF(&r, &g, &b, &a);
16297 fschmid 1143
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1144
                                                qStopColors[1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1145
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1146
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
1147
                                                cairo_pattern_mesh_end_patch(mpat);
1148
                                                cairo_pattern_mesh_begin_patch(mpat);
1149
                                                cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
1150
                                                cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
1151
                                                cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
1152
#ifdef HAVE_PRIVATE_CAIRO
1153
                                                cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
1154
#endif
14981 fschmid 1155
                                                qStopColors[0].getRgbF(&r, &g, &b, &a);
16297 fschmid 1156
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1157
                                                qStopColors[1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1158
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1159
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
1160
                                                cairo_pattern_mesh_end_patch(mpat);
1161
                                                cairo_pattern_mesh_begin_patch(mpat);
1162
                                                cairo_pattern_mesh_move_to(mpat, centerP.x(), centerP.y());
1163
                                                cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
1164
                                                cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
1165
#ifdef HAVE_PRIVATE_CAIRO
1166
                                                cairo_pattern_mesh_line_to(mpat, centerP.x(), centerP.y());
1167
#endif
14981 fschmid 1168
                                                qStopColors[0].getRgbF(&r, &g, &b, &a);
16297 fschmid 1169
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1170
                                                qStopColors[1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1171
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1172
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
1173
                                                cairo_pattern_mesh_end_patch(mpat);
14981 fschmid 1174
                                        }
1175
                                        else
1176
                                        {
16297 fschmid 1177
                                                cairo_pattern_mesh_begin_patch(mpat);
1178
                                                cairo_pattern_mesh_move_to(mpat, e1s.x2(), e1s.y2());
1179
                                                cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
1180
                                                cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
1181
                                                cairo_pattern_mesh_line_to(mpat, e2s.x2(), e2s.y2());
14981 fschmid 1182
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1183
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1184
                                                qStopColors[offset].getRgbF(&r, &g, &b, &a);
16297 fschmid 1185
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1186
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
14981 fschmid 1187
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1188
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
1189
                                                cairo_pattern_mesh_end_patch(mpat);
1190
                                                cairo_pattern_mesh_begin_patch(mpat);
1191
                                                cairo_pattern_mesh_move_to(mpat, e2s.x2(), e2s.y2());
1192
                                                cairo_pattern_mesh_line_to(mpat, e2.x2(), e2.y2());
1193
                                                cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
1194
                                                cairo_pattern_mesh_line_to(mpat, e3s.x2(), e3s.y2());
14981 fschmid 1195
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1196
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1197
                                                qStopColors[offset].getRgbF(&r, &g, &b, &a);
16297 fschmid 1198
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1199
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
14981 fschmid 1200
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1201
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
1202
                                                cairo_pattern_mesh_end_patch(mpat);
1203
                                                cairo_pattern_mesh_begin_patch(mpat);
1204
                                                cairo_pattern_mesh_move_to(mpat, e3s.x2(), e3s.y2());
1205
                                                cairo_pattern_mesh_line_to(mpat, e3.x2(), e3.y2());
1206
                                                cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
1207
                                                cairo_pattern_mesh_line_to(mpat, e4s.x2(), e4s.y2());
14981 fschmid 1208
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1209
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1210
                                                qStopColors[offset].getRgbF(&r, &g, &b, &a);
16297 fschmid 1211
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1212
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
14981 fschmid 1213
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1214
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
1215
                                                cairo_pattern_mesh_end_patch(mpat);
1216
                                                cairo_pattern_mesh_begin_patch(mpat);
1217
                                                cairo_pattern_mesh_move_to(mpat, e4s.x2(), e4s.y2());
1218
                                                cairo_pattern_mesh_line_to(mpat, e4.x2(), e4.y2());
1219
                                                cairo_pattern_mesh_line_to(mpat, e1.x2(), e1.y2());
1220
                                                cairo_pattern_mesh_line_to(mpat, e1s.x2(), e1s.y2());
14981 fschmid 1221
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1222
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
14981 fschmid 1223
                                                qStopColors[offset].getRgbF(&r, &g, &b, &a);
16297 fschmid 1224
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1225
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
14981 fschmid 1226
                                                qStopColors[offset-1].getRgbF(&r, &g, &b, &a);
16297 fschmid 1227
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
1228
                                                cairo_pattern_mesh_end_patch(mpat);
14981 fschmid 1229
                                        }
1230
                                }
1231
                                cairo_pattern_set_filter(mpat, CAIRO_FILTER_GOOD);
1232
                                cairo_set_source(cr, mpat);
1233
                                cairo_paint_with_alpha(cr, 1.0);
1234
                                pat = cairo_pattern_create_for_surface(img);
15024 fschmid 1235
                                cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD);
14981 fschmid 1236
                                cairo_pattern_set_filter(pat, CAIRO_FILTER_GOOD);
15058 fschmid 1237
#else
1238
                                double r, g, b;
1239
                                m_fill.getRgbF(&r, &g, &b);
1240
                                pat = cairo_pattern_create_rgba(r, g, b, 1.0);
14981 fschmid 1241
#endif
1242
                        }
15024 fschmid 1243
                        else if (fill_gradient.type() == VGradient::mesh)
1244
                        {
16297 fschmid 1245
// #ifdef HAVE_PRIVATE_CAIRO
1246
#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) || HAVE_PRIVATE_CAIRO)
15024 fschmid 1247
                                double p3x = gradPatchP3.x();
1248
                                double p3y = gradPatchP3.y();
1249
                                img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
1250
                                cr = cairo_create(img);
1251
                                cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
1252
                                cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1253
                                cairo_set_tolerance(cr, 0.5 );
1254
                                double r, g, b, a;
1255
                                mpat = cairo_pattern_create_mesh();
1256
                                for (int grow = 0; grow < meshGradientArray.count()-1; grow++)
1257
                                {
1258
                                        for (int gcol = 0; gcol < meshGradientArray[grow].count()-1; gcol++)
1259
                                        {
1260
                                                meshPoint mp1 = meshGradientArray[grow][gcol];
1261
                                                meshPoint mp2 = meshGradientArray[grow][gcol+1];
1262
                                                meshPoint mp3 = meshGradientArray[grow+1][gcol+1];
1263
                                                meshPoint mp4 = meshGradientArray[grow+1][gcol];
16297 fschmid 1264
                                                cairo_pattern_mesh_begin_patch(mpat);
1265
                                                cairo_pattern_mesh_move_to(mpat, mp1.gridPoint.x(), mp1.gridPoint.y());
1266
                                                cairo_pattern_mesh_curve_to(mpat, mp1.controlRight.x(), mp1.controlRight.y(), mp2.controlLeft.x(), mp2.controlLeft.y(), mp2.gridPoint.x(), mp2.gridPoint.y());
1267
                                                cairo_pattern_mesh_curve_to(mpat, mp2.controlBottom.x(), mp2.controlBottom.y(), mp3.controlTop.x(), mp3.controlTop.y(), mp3.gridPoint.x(), mp3.gridPoint.y());
1268
                                                cairo_pattern_mesh_curve_to(mpat, mp3.controlLeft.x(), mp3.controlLeft.y(), mp4.controlRight.x(), mp4.controlRight.y(), mp4.gridPoint.x(), mp4.gridPoint.y());
1269
                                                cairo_pattern_mesh_curve_to(mpat, mp4.controlTop.x(), mp4.controlTop.y(), mp1.controlBottom.x(), mp1.controlBottom.y(), mp1.gridPoint.x(), mp1.gridPoint.y());
15024 fschmid 1270
                                                mp1.color.getRgbF(&r, &g, &b, &a);
16297 fschmid 1271
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
15024 fschmid 1272
                                                mp2.color.getRgbF(&r, &g, &b, &a);
16297 fschmid 1273
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
15024 fschmid 1274
                                                mp3.color.getRgbF(&r, &g, &b, &a);
16297 fschmid 1275
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
15024 fschmid 1276
                                                mp4.color.getRgbF(&r, &g, &b, &a);
16297 fschmid 1277
                                                cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
1278
                                                cairo_pattern_mesh_end_patch(mpat);
15024 fschmid 1279
                                        }
1280
                                }
1281
                                cairo_pattern_set_filter(mpat, CAIRO_FILTER_BEST);
1282
                                cairo_set_source(cr, mpat);
1283
                                cairo_paint_with_alpha(cr, 1.0);
1284
                                pat = cairo_pattern_create_for_surface(img);
1285
                                cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
1286
                                cairo_pattern_set_filter(pat, CAIRO_FILTER_BEST);
1287
#else
1288
                                double p3x = gradPatchP3.x();
1289
                                double p3y = gradPatchP3.y();
1290
                                img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
1291
                                cr = cairo_create(img);
1292
                                cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
1293
                                cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1294
                                cairo_set_tolerance(cr, 0.5 );
1295
                                double r, g, b, a;
1296
                                for (int grow = 0; grow < meshGradientArray.count()-1; grow++)
1297
                                {
1298
                                        for (int gcol = 0; gcol < meshGradientArray[grow].count()-1; gcol++)
1299
                                        {
1300
                                                meshPoint mp1 = meshGradientArray[grow][gcol];
1301
                                                meshPoint mp2 = meshGradientArray[grow][gcol+1];
1302
                                                meshPoint mp3 = meshGradientArray[grow+1][gcol+1];
1303
                                                meshPoint mp4 = meshGradientArray[grow+1][gcol];
1304
                                                cairo_new_path( cr );
1305
                                                cairo_move_to(cr, mp1.gridPoint.x(), mp1.gridPoint.y());
1306
                                                cairo_curve_to(cr, mp1.controlRight.x(), mp1.controlRight.y(), mp2.controlLeft.x(), mp2.controlLeft.y(), mp2.gridPoint.x(), mp2.gridPoint.y());
1307
                                                cairo_curve_to(cr, mp2.controlBottom.x(), mp2.controlBottom.y(), mp3.controlTop.x(), mp3.controlTop.y(), mp3.gridPoint.x(), mp3.gridPoint.y());
1308
                                                cairo_curve_to(cr, mp3.controlLeft.x(), mp3.controlLeft.y(), mp4.controlRight.x(), mp4.controlRight.y(), mp4.gridPoint.x(), mp4.gridPoint.y());
1309
                                                cairo_curve_to(cr, mp4.controlTop.x(), mp4.controlTop.y(), mp1.controlBottom.x(), mp1.controlBottom.y(), mp1.gridPoint.x(), mp1.gridPoint.y());
1310
                                                cairo_close_path( cr );
1311
                                                double acr = 0.0;
1312
                                                double acg = 0.0;
1313
                                                double acb = 0.0;
1314
                                                double aca = 0.0;
1315
                                                mp1.color.getRgbF(&r, &g, &b, &a);
1316
                                                acr += r;
1317
                                                acg += g;
1318
                                                acb += b;
1319
                                                aca += a;
1320
                                                mp2.color.getRgbF(&r, &g, &b, &a);
1321
                                                acr += r;
1322
                                                acg += g;
1323
                                                acb += b;
1324
                                                aca += a;
1325
                                                mp3.color.getRgbF(&r, &g, &b, &a);
1326
                                                acr += r;
1327
                                                acg += g;
1328
                                                acb += b;
1329
                                                aca += a;
1330
                                                mp4.color.getRgbF(&r, &g, &b, &a);
1331
                                                acr += r;
1332
                                                acg += g;
1333
                                                acb += b;
1334
                                                aca += a;
1335
                                                cairo_set_source_rgba(cr, acr / 4.0, acg / 4.0, acb / 4.0, aca / 4.0);         
1336
                                                cairo_fill(cr);
1337
                                        }
1338
                                }
1339
                                pat = cairo_pattern_create_for_surface(img);
1340
                                cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
1341
                                cairo_pattern_set_filter(pat, CAIRO_FILTER_BEST);
1342
#endif
1343
                        }
16729 fschmid 1344
                        else if (fill_gradient.type() == VGradient::freemesh)
1345
                        {
1346
// #ifdef HAVE_PRIVATE_CAIRO
1347
#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2) || HAVE_PRIVATE_CAIRO)
1348
                                double p3x = gradPatchP3.x();
1349
                                double p3y = gradPatchP3.y();
1350
                                img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
1351
                                cr = cairo_create(img);
1352
                                cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
1353
                                cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1354
                                cairo_set_tolerance(cr, 0.5 );
1355
                                double r, g, b, a;
1356
                                mpat = cairo_pattern_create_mesh();
1357
                                for (int col = 0; col < meshGradientPatches.count(); col++)
1358
                                {
1359
                                        meshGradientPatch patch = meshGradientPatches[col];
1360
                                        meshPoint mp1 = patch.TL;
1361
                                        meshPoint mp2 = patch.TR;
1362
                                        meshPoint mp3 = patch.BR;
1363
                                        meshPoint mp4 = patch.BL;
1364
                                        cairo_pattern_mesh_begin_patch(mpat);
1365
                                        cairo_pattern_mesh_move_to(mpat, mp1.gridPoint.x(), mp1.gridPoint.y());
1366
                                        cairo_pattern_mesh_curve_to(mpat, mp1.controlRight.x(), mp1.controlRight.y(), mp2.controlLeft.x(), mp2.controlLeft.y(), mp2.gridPoint.x(), mp2.gridPoint.y());
1367
                                        cairo_pattern_mesh_curve_to(mpat, mp2.controlBottom.x(), mp2.controlBottom.y(), mp3.controlTop.x(), mp3.controlTop.y(), mp3.gridPoint.x(), mp3.gridPoint.y());
1368
                                        cairo_pattern_mesh_curve_to(mpat, mp3.controlLeft.x(), mp3.controlLeft.y(), mp4.controlRight.x(), mp4.controlRight.y(), mp4.gridPoint.x(), mp4.gridPoint.y());
1369
                                        cairo_pattern_mesh_curve_to(mpat, mp4.controlTop.x(), mp4.controlTop.y(), mp1.controlBottom.x(), mp1.controlBottom.y(), mp1.gridPoint.x(), mp1.gridPoint.y());
1370
                                        mp1.color.getRgbF(&r, &g, &b, &a);
1371
                                        cairo_pattern_mesh_set_corner_color_rgba(mpat, 0, r, g, b, a);
1372
                                        mp2.color.getRgbF(&r, &g, &b, &a);
1373
                                        cairo_pattern_mesh_set_corner_color_rgba(mpat, 1, r, g, b, a);
1374
                                        mp3.color.getRgbF(&r, &g, &b, &a);
1375
                                        cairo_pattern_mesh_set_corner_color_rgba(mpat, 2, r, g, b, a);
1376
                                        mp4.color.getRgbF(&r, &g, &b, &a);
1377
                                        cairo_pattern_mesh_set_corner_color_rgba(mpat, 3, r, g, b, a);
1378
                                        cairo_pattern_mesh_end_patch(mpat);
1379
                                }
1380
                                cairo_pattern_set_filter(mpat, CAIRO_FILTER_BEST);
1381
                                cairo_set_source(cr, mpat);
1382
                                cairo_paint_with_alpha(cr, 1.0);
1383
                                pat = cairo_pattern_create_for_surface(img);
1384
                                cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
1385
                                cairo_pattern_set_filter(pat, CAIRO_FILTER_BEST);
1386
#else
1387
                                double p3x = gradPatchP3.x();
1388
                                double p3y = gradPatchP3.y();
1389
                                img = cairo_surface_create_similar(cairo_get_target(m_cr), CAIRO_CONTENT_COLOR_ALPHA, p3x, p3y);
1390
                                cr = cairo_create(img);
1391
                                cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
1392
                                cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1393
                                cairo_set_tolerance(cr, 0.5 );
1394
                                double r, g, b, a;
1395
                                for (int col = 0; col < meshGradientPatches.count(); col++)
1396
                                {
16812 jghali 1397
                                        meshGradientPatch patch = meshGradientPatches[col];
16729 fschmid 1398
                                        meshPoint mp1 = patch.TL;
1399
                                        meshPoint mp2 = patch.TR;
1400
                                        meshPoint mp3 = patch.BR;
1401
                                        meshPoint mp4 = patch.BL;
1402
                                        cairo_new_path( cr );
16812 jghali 1403
                                        cairo_move_to(cr, mp1.gridPoint.x(), mp1.gridPoint.y());
1404
                                        cairo_curve_to(cr, mp1.controlRight.x(), mp1.controlRight.y(), mp2.controlLeft.x(), mp2.controlLeft.y(), mp2.gridPoint.x(), mp2.gridPoint.y());
1405
                                        cairo_curve_to(cr, mp2.controlBottom.x(), mp2.controlBottom.y(), mp3.controlTop.x(), mp3.controlTop.y(), mp3.gridPoint.x(), mp3.gridPoint.y());
1406
                                        cairo_curve_to(cr, mp3.controlLeft.x(), mp3.controlLeft.y(), mp4.controlRight.x(), mp4.controlRight.y(), mp4.gridPoint.x(), mp4.gridPoint.y());
1407
                                        cairo_curve_to(cr, mp4.controlTop.x(), mp4.controlTop.y(), mp1.controlBottom.x(), mp1.controlBottom.y(), mp1.gridPoint.x(), mp1.gridPoint.y());
16729 fschmid 1408
                                        cairo_close_path( cr );
1409
                                        double acr = 0.0;
1410
                                        double acg = 0.0;
1411
                                        double acb = 0.0;
1412
                                        double aca = 0.0;
1413
                                        mp1.color.getRgbF(&r, &g, &b, &a);
1414
                                        acr += r;
1415
                                        acg += g;
1416
                                        acb += b;
1417
                                        aca += a;
1418
                                        mp2.color.getRgbF(&r, &g, &b, &a);
1419
                                        acr += r;
1420
                                        acg += g;
1421
                                        acb += b;
1422
                                        aca += a;
1423
                                        mp3.color.getRgbF(&r, &g, &b, &a);
1424
                                        acr += r;
1425
                                        acg += g;
1426
                                        acb += b;
1427
                                        aca += a;
1428
                                        mp4.color.getRgbF(&r, &g, &b, &a);
1429
                                        acr += r;
1430
                                        acg += g;
1431
                                        acb += b;
1432
                                        aca += a;
1433
                                        cairo_set_source_rgba(cr, acr / 4.0, acg / 4.0, acb / 4.0, aca / 4.0);
1434
                                        cairo_fill(cr);
1435
                                }
1436
                                pat = cairo_pattern_create_for_surface(img);
1437
                                cairo_pattern_set_extend(pat, CAIRO_EXTEND_NONE);
1438
                                cairo_pattern_set_filter(pat, CAIRO_FILTER_BEST);
1439
#endif
1440
                        }
14284 fschmid 1441
                        else
1442
                        {
15202 jghali 1443
                                bool   isFirst = true;
1444
                                double rampPoint, lastPoint = 0.0;
14952 fschmid 1445
                                double x1 = fill_gradient.origin().x();
1446
                                double y1 = fill_gradient.origin().y();
1447
                                double x2 = fill_gradient.vector().x();
1448
                                double y2 = fill_gradient.vector().y();
1449
                                double fx = fill_gradient.focalPoint().x();
1450
                                double fy = fill_gradient.focalPoint().y();
1451
                                if (fill_gradient.type() == VGradient::linear)
1452
                                        pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
1453
                                else
1454
                                        pat = cairo_pattern_create_radial (fx, fy, 0, x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)));
1455
                                cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD);
1456
                                cairo_pattern_set_filter(pat, CAIRO_FILTER_GOOD);
1457
                                QList<VColorStop*> colorStops = fill_gradient.colorStops();
1458
                                QColor qStopColor;
1459
                                for( int offset = 0 ; offset < colorStops.count() ; offset++ )
1460
                                {
1461
                                        qStopColor = colorStops[ offset ]->color;
15202 jghali 1462
                                        rampPoint  = colorStops[ offset ]->rampPoint;
1463
                                        if ((lastPoint == rampPoint) && (!isFirst))
1464
                                                continue;
1465
                                        isFirst = false;
14952 fschmid 1466
                                        int h, s, v, sneu, vneu;
1467
                                        int shad = colorStops[offset]->shade;
1468
                                        qStopColor.getHsv(&h, &s, &v);
1469
                                        sneu = s * shad / 100;
1470
                                        vneu = 255 - ((255 - v) * shad / 100);
1471
                                        qStopColor.setHsv(h, sneu, vneu);
1472
                                        double a = colorStops[offset]->opacity;
1473
                                        double r, g, b;
1474
                                        qStopColor.getRgbF(&r, &g, &b);
1475
                                        cairo_pattern_add_color_stop_rgba (pat, colorStops[ offset ]->rampPoint, r, g, b, a);
15202 jghali 1476
                                        lastPoint = rampPoint;
14952 fschmid 1477
                                }
1478
                                cairo_matrix_t matrix;
1479
                                QTransform qmatrix;
1480
                                if (fill_gradient.type() == VGradient::radial)
1481
                                {
1482
                                        double rotEnd = xy2Deg(x2 - x1, y2 - y1);
1483
                                        qmatrix.translate(x1, y1);
1484
                                        qmatrix.rotate(rotEnd);
1485
                                        qmatrix.shear(gradientSkew, 0);
1486
                                        qmatrix.translate(0, y1 * (1.0 - gradientScale));
1487
                                        qmatrix.translate(-x1, -y1);
1488
                                        qmatrix.scale(1, gradientScale);
1489
                                }
1490
                                else
1491
                                {
1492
                                        qmatrix.translate(x1, y1);
1493
                                        qmatrix.shear(-gradientSkew, 0);
1494
                                        qmatrix.translate(-x1, -y1);
1495
                                }
1496
                                cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
1497
                                cairo_matrix_invert(&matrix);
1498
                                cairo_pattern_set_matrix (pat, &matrix);
14284 fschmid 1499
                        }
3113 fschmid 1500
                        cairo_set_source (m_cr, pat);
1501
                        cairo_clip_preserve (m_cr);
14308 fschmid 1502
                        if (maskMode > 0)
14297 fschmid 1503
                        {
14298 fschmid 1504
                                cairo_pattern_t *patM = getMaskPattern();
14306 fschmid 1505
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1506
                                setRasterOp(m_blendModeFill);
1507
#endif
14297 fschmid 1508
                                cairo_mask(m_cr, patM);
16732 fschmid 1509
                                if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
14318 fschmid 1510
                                        cairo_surface_destroy(imageMask);
14297 fschmid 1511
                                cairo_pattern_destroy (patM);
1512
                        }
1513
                        else
14306 fschmid 1514
                        {
1515
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1516
                                setRasterOp(m_blendModeFill);
1517
#endif
14297 fschmid 1518
                                cairo_paint_with_alpha (m_cr, fill_trans);
14306 fschmid 1519
                        }
3113 fschmid 1520
                        cairo_pattern_destroy (pat);
16297 fschmid 1521
// #ifdef HAVE_PRIVATE_CAIRO
1522
#if (CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 11, 2)  || HAVE_PRIVATE_CAIRO)
16729 fschmid 1523
                        if ((fill_gradient.type() == VGradient::fourcolor) || (fill_gradient.type() == VGradient::diamond) || (fill_gradient.type() == VGradient::mesh) || (fill_gradient.type() == VGradient::freemesh))
14952 fschmid 1524
                        {
1525
                                cairo_surface_destroy(img);
1526
                                cairo_pattern_destroy(mpat);
1527
                                cairo_destroy( cr );
1528
                        }
15024 fschmid 1529
#else
16729 fschmid 1530
                        if ((fill_gradient.type() == VGradient::mesh) || (fill_gradient.type() == VGradient::freemesh))
15024 fschmid 1531
                        {
1532
                                cairo_surface_destroy(img);
1533
                                cairo_destroy( cr );
1534
                        }
14952 fschmid 1535
#endif
3113 fschmid 1536
                }
6368 fschmid 1537
                else if (fillMode == 3)
3113 fschmid 1538
                {
13943 fschmid 1539
                        cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_NONE);
11383 fschmid 1540
                        cairo_surface_t *image2 = cairo_image_surface_create_for_data ((uchar*)m_pattern->getPattern()->bits(), CAIRO_FORMAT_ARGB32, m_pattern->getPattern()->width(), m_pattern->getPattern()->height(), m_pattern->getPattern()->width()*4);
1541
                        cairo_pattern_t *m_pat = cairo_pattern_create_for_surface(image2);
1542
                        cairo_pattern_set_extend(m_pat, CAIRO_EXTEND_REPEAT);
14952 fschmid 1543
                        cairo_pattern_set_filter(m_pat, CAIRO_FILTER_GOOD);
11383 fschmid 1544
                        cairo_matrix_t matrix;
13951 fschmid 1545
                        QTransform qmatrix;
11383 fschmid 1546
                        qmatrix.translate(patternOffsetX, patternOffsetY);
1547
                        qmatrix.rotate(patternRotation);
14260 fschmid 1548
                        qmatrix.shear(-patternSkewX, patternSkewY);
11383 fschmid 1549
                        qmatrix.scale(patternScaleX, patternScaleY);
13941 fschmid 1550
                        qmatrix.scale(m_pattern->width / static_cast<double>(m_pattern->getPattern()->width()), m_pattern->height / static_cast<double>(m_pattern->getPattern()->height()));
14276 fschmid 1551
                        if (patternMirrorX)
1552
                                qmatrix.scale(-1, 1);
1553
                        if (patternMirrorY)
1554
                                qmatrix.scale(1, -1);
11383 fschmid 1555
                        cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
1556
                        cairo_matrix_invert(&matrix);
1557
                        cairo_pattern_set_matrix (m_pat, &matrix);
1558
                        cairo_set_source (m_cr, m_pat);
1559
                        cairo_clip_preserve (m_cr);
14308 fschmid 1560
                        if (maskMode > 0)
14297 fschmid 1561
                        {
14298 fschmid 1562
                                cairo_pattern_t *patM = getMaskPattern();
14306 fschmid 1563
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1564
                                setRasterOp(m_blendModeFill);
1565
#endif
14297 fschmid 1566
                                cairo_mask(m_cr, patM);
16732 fschmid 1567
                                if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
14318 fschmid 1568
                                        cairo_surface_destroy(imageMask);
14297 fschmid 1569
                                cairo_pattern_destroy (patM);
1570
                        }
1571
                        else
14306 fschmid 1572
                        {
1573
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1574
                                setRasterOp(m_blendModeFill);
1575
#endif
14297 fschmid 1576
                                cairo_paint_with_alpha (m_cr, fill_trans);
14306 fschmid 1577
                        }
11383 fschmid 1578
                        cairo_pattern_destroy (m_pat);
1579
                        cairo_surface_destroy (image2);
13943 fschmid 1580
                        cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_DEFAULT);
3113 fschmid 1581
                }
1582
        }
1583
        else
1584
        {
13013 fschmid 1585
                if( LineWidth == 0 )
1586
                        cairo_set_line_width( m_cr, 1.0 / m_zoomFactor );
1587
                else
1588
                        cairo_set_line_width( m_cr, LineWidth );
3113 fschmid 1589
                if( m_array.count() > 0 )
12055 jghali 1590
                        cairo_set_dash( m_cr, m_array.data(), m_array.count(), m_offset);
3113 fschmid 1591
                else
1592
                        cairo_set_dash( m_cr, NULL, 0, 0 );
14168 fschmid 1593
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
3113 fschmid 1594
                if( PLineEnd == Qt::RoundCap )
1595
                        cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_ROUND);
1596
                else if( PLineEnd == Qt::SquareCap )
1597
                        cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_SQUARE);
1598
                else if( PLineEnd == Qt::FlatCap )
1599
                        cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_BUTT);
1600
                if( PLineJoin == Qt::RoundJoin )
1601
                        cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_ROUND );
1602
                else if( PLineJoin == Qt::BevelJoin )
1603
                        cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_BEVEL );
1604
                else if( PLineJoin == Qt::MiterJoin )
1605
                        cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_MITER );
14168 fschmid 1606
                if (strokeMode == 3)
1607
                {
1608
                        cairo_push_group(m_cr);
1609
                        cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_NONE);
1610
                        cairo_surface_t *image2 = cairo_image_surface_create_for_data ((uchar*)m_pattern->getPattern()->bits(), CAIRO_FORMAT_ARGB32, m_pattern->getPattern()->width(), m_pattern->getPattern()->height(), m_pattern->getPattern()->width()*4);
1611
                        cairo_pattern_t *m_pat = cairo_pattern_create_for_surface(image2);
1612
                        cairo_pattern_set_extend(m_pat, CAIRO_EXTEND_REPEAT);
14952 fschmid 1613
                        cairo_pattern_set_filter(m_pat, CAIRO_FILTER_GOOD);
14168 fschmid 1614
                        cairo_matrix_t matrix;
1615
                        QTransform qmatrix;
1616
                        qmatrix.translate(-LineWidth / 2.0, -LineWidth / 2.0);
1617
                        qmatrix.translate(patternOffsetX, patternOffsetY);
1618
                        qmatrix.rotate(patternRotation);
14260 fschmid 1619
                        qmatrix.shear(-patternSkewX, patternSkewY);
14168 fschmid 1620
                        qmatrix.scale(patternScaleX, patternScaleY);
1621
                        qmatrix.scale(m_pattern->width / static_cast<double>(m_pattern->getPattern()->width()), m_pattern->height / static_cast<double>(m_pattern->getPattern()->height()));
14276 fschmid 1622
                        if (patternMirrorX)
1623
                                qmatrix.scale(-1, 1);
1624
                        if (patternMirrorY)
1625
                                qmatrix.scale(1, -1);
14168 fschmid 1626
                        cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
1627
                        cairo_matrix_invert(&matrix);
1628
                        cairo_pattern_set_matrix (m_pat, &matrix);
1629
                        cairo_set_source (m_cr, m_pat);
1630
                        cairo_stroke_preserve( m_cr );
1631
                        cairo_pattern_destroy (m_pat);
1632
                        cairo_surface_destroy (image2);
1633
                        cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_DEFAULT);
1634
                        cairo_pop_group_to_source (m_cr);
14306 fschmid 1635
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1636
                        setRasterOp(m_blendModeStroke);
1637
#endif
14168 fschmid 1638
                        cairo_paint_with_alpha (m_cr, stroke_trans);
1639
                }
1640
                else if (strokeMode == 2)
1641
                {
1642
                        cairo_push_group(m_cr);
1643
                        cairo_pattern_t *pat;
15202 jghali 1644
                        bool   isFirst = true;
1645
                        double rampPoint, lastPoint = 0.0;
14168 fschmid 1646
                        double x1 = stroke_gradient.origin().x();
1647
                        double y1 = stroke_gradient.origin().y();
1648
                        double x2 = stroke_gradient.vector().x();
1649
                        double y2 = stroke_gradient.vector().y();
14278 fschmid 1650
                        double fx = stroke_gradient.focalPoint().x();
1651
                        double fy = stroke_gradient.focalPoint().y();
14168 fschmid 1652
                        if (stroke_gradient.type() == VGradient::linear)
1653
                                pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
1654
                        else
14278 fschmid 1655
                                pat = cairo_pattern_create_radial (fx, fy, 0, x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)));
14952 fschmid 1656
                        cairo_pattern_set_extend(pat, CAIRO_EXTEND_PAD);
1657
                        cairo_pattern_set_filter(pat, CAIRO_FILTER_GOOD);
14168 fschmid 1658
                        QList<VColorStop*> colorStops = stroke_gradient.colorStops();
1659
                        QColor qStopColor;
1660
                        for( int offset = 0 ; offset < colorStops.count() ; offset++ )
1661
                        {
1662
                                qStopColor = colorStops[ offset ]->color;
15202 jghali 1663
                                rampPoint  = colorStops[ offset ]->rampPoint;
1664
                                if ((lastPoint == rampPoint) && (!isFirst))
1665
                                        continue;
1666
                                isFirst = false;
14168 fschmid 1667
                                int h, s, v, sneu, vneu;
1668
                                int shad = colorStops[offset]->shade;
1669
                                qStopColor.getHsv(&h, &s, &v);
1670
                                sneu = s * shad / 100;
1671
                                vneu = 255 - ((255 - v) * shad / 100);
1672
                                qStopColor.setHsv(h, sneu, vneu);
1673
                                double a = colorStops[offset]->opacity;
1674
                                double r, g, b;
1675
                                qStopColor.getRgbF(&r, &g, &b);
15202 jghali 1676
                                cairo_pattern_add_color_stop_rgba (pat, rampPoint, r, g, b, a);
1677
                                lastPoint = rampPoint;
14168 fschmid 1678
                        }
14284 fschmid 1679
                        cairo_matrix_t matrix;
1680
                        QTransform qmatrix;
1681
                        if (stroke_gradient.type() == VGradient::radial)
1682
                        {
1683
                                double rotEnd = xy2Deg(x2 - x1, y2 - y1);
1684
                                qmatrix.translate(x1, y1);
1685
                                qmatrix.rotate(rotEnd);
1686
                                qmatrix.shear(gradientSkew, 0);
1687
                                qmatrix.translate(0, y1 * (1.0 - gradientScale));
1688
                                qmatrix.translate(-x1, -y1);
1689
                                qmatrix.scale(1, gradientScale);
1690
                        }
1691
                        else
1692
                        {
1693
                                qmatrix.translate(x1, y1);
1694
                                qmatrix.shear(-gradientSkew, 0);
1695
                                qmatrix.translate(-x1, -y1);
1696
                        }
1697
                        cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
1698
                        cairo_matrix_invert(&matrix);
1699
                        cairo_pattern_set_matrix (pat, &matrix);
14168 fschmid 1700
                        cairo_set_source (m_cr, pat);
1701
                        cairo_stroke_preserve( m_cr );
1702
                        cairo_pattern_destroy (pat);
1703
                        cairo_pop_group_to_source (m_cr);
14306 fschmid 1704
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1705
                        setRasterOp(m_blendModeStroke);
1706
#endif
14168 fschmid 1707
                        cairo_paint_with_alpha (m_cr, stroke_trans);
1708
                }
1709
                else
1710
                {
1711
                        double r, g, b;
1712
                        m_stroke.getRgbF(&r, &g, &b);
1713
                        cairo_set_source_rgba( m_cr, r, g, b, stroke_trans );
14306 fschmid 1714
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1715
                        setRasterOp(m_blendModeStroke);
1716
#endif
14168 fschmid 1717
                        cairo_stroke_preserve( m_cr );
1718
                }
3113 fschmid 1719
        }
14308 fschmid 1720
        cairo_restore( m_cr );
14306 fschmid 1721
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
9319 fschmid 1722
}
68 Franz 1723
 
267 Franz 1724
void ScPainter::setClipPath()
1725
{
3113 fschmid 1726
        cairo_clip (m_cr);
267 Franz 1727
}
1728
 
14825 fschmid 1729
void ScPainter::drawImage( QImage *image)
68 Franz 1730
{
6856 fschmid 1731
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 2, 6)
11383 fschmid 1732
/*
1733
        cairo_surface_t *image3 = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_ARGB32, image->width(), image->height(), image->width()*4);
1734
        cairo_set_source_surface (m_cr, image3, 0, 0);
1735
        cairo_paint_with_alpha (m_cr, fill_trans);
1736
        cairo_surface_destroy (image3);
1737
*/
6856 fschmid 1738
/* Code with Layers, crashes on cairo_push_group */
7141 fschmid 1739
//      cairo_scale(m_cr, m_zoomFactor, m_zoomFactor);
6312 fschmid 1740
        cairo_push_group(m_cr);
14307 fschmid 1741
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
3113 fschmid 1742
        cairo_set_fill_rule(m_cr, cairo_get_fill_rule(m_cr));
6312 fschmid 1743
        cairo_surface_t *image2  = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_RGB24, image->width(), image->height(), image->width()*4);
1744
        cairo_surface_t *image3 = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_ARGB32, image->width(), image->height(), image->width()*4);
1745
        cairo_set_source_surface (m_cr, image2, 0, 0);
1746
    cairo_mask_surface (m_cr, image3, 0, 0);
1747
        cairo_surface_destroy (image2);
1748
        cairo_surface_destroy (image3);
1749
        cairo_pop_group_to_source (m_cr);
14307 fschmid 1750
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
1751
        setRasterOp(m_blendModeFill);
1752
#endif
14308 fschmid 1753
        if (maskMode > 0)
14265 fschmid 1754
        {
14298 fschmid 1755
                cairo_pattern_t *patM = getMaskPattern();
1756
                cairo_mask(m_cr, patM);
16732 fschmid 1757
                if ((maskMode == 2) || (maskMode == 4) || (maskMode == 5) || (maskMode == 6))
14318 fschmid 1758
                        cairo_surface_destroy(imageMask);
14298 fschmid 1759
                cairo_pattern_destroy(patM);
14265 fschmid 1760
        }
1761
        else
14298 fschmid 1762
                cairo_paint_with_alpha (m_cr, fill_trans);
14307 fschmid 1763
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
6856 fschmid 1764
#else
6312 fschmid 1765
/* Working code, sadly we need to create an additional mask image with the same size as the image to be painted */
6314 fschmid 1766
        cairo_surface_t *image3;
1767
        QImage mask;
6312 fschmid 1768
        cairo_set_fill_rule(m_cr, cairo_get_fill_rule(m_cr));
1769
        cairo_surface_t *image2  = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_RGB24, image->width(), image->height(), image->width()*4);
6314 fschmid 1770
        if (fill_trans != 1.0)
6312 fschmid 1771
        {
11541 fschmid 1772
                mask = QImage(image->width(), image->height(), QImage::Format_Mono);
6314 fschmid 1773
                for( int yi = 0; yi < image->height(); ++yi )
6312 fschmid 1774
                {
6314 fschmid 1775
                        QRgb * s = (QRgb*)(image->scanLine( yi ));
6315 fschmid 1776
                        unsigned char *d = (unsigned char *)(mask.scanLine( yi ));
6314 fschmid 1777
                        for( int xi=0; xi < image->width(); ++xi )
1778
                        {
6315 fschmid 1779
                                *d++ = static_cast<unsigned char>(qAlpha(*s++) * fill_trans);
6314 fschmid 1780
                        }
6312 fschmid 1781
                }
6315 fschmid 1782
                int adj;
1783
                if (image->width() % 4 == 0)
1784
                        adj = 0;
1785
                else
1786
                        adj = 4 - (image->width() % 4);
1787
                image3 = cairo_image_surface_create_for_data ((uchar*)mask.bits(), CAIRO_FORMAT_A8, image->width(), image->height(), image->width() + adj);
6312 fschmid 1788
        }
6314 fschmid 1789
        else
1790
                image3 = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_ARGB32, image->width(), image->height(), image->width()*4);
3113 fschmid 1791
        cairo_set_source_surface (m_cr, image2, 0, 0);
6312 fschmid 1792
        cairo_mask_surface (m_cr, image3, 0, 0);
1793
        cairo_surface_destroy (image2);
1794
        cairo_surface_destroy (image3);
6856 fschmid 1795
#endif
68 Franz 1796
}
1797
 
264 Franz 1798
void ScPainter::setupPolygon(FPointArray *points, bool closed)
68 Franz 1799
{
1800
        bool nPath = true;
11004 fschmid 1801
        bool first = true;
16763 fschmid 1802
        FPoint np, np1, np2, np3, np4, firstP;
68 Franz 1803
        if (points->size() > 3)
3113 fschmid 1804
        {
1805
                newPath();
1806
                for (uint poi=0; poi<points->size()-3; poi += 4)
68 Franz 1807
                {
3113 fschmid 1808
                        if (points->point(poi).x() > 900000)
1809
                        {
1810
                                nPath = true;
1811
                                continue;
1812
                        }
1813
                        if (nPath)
1814
                        {
1815
                                np = points->point(poi);
16763 fschmid 1816
                                if ((!first) && (closed) && (np4 == firstP))
11004 fschmid 1817
                                        cairo_close_path( m_cr );
11196 fschmid 1818
                        cairo_move_to( m_cr, np.x(), np.y());
16763 fschmid 1819
                                firstP = np;
3113 fschmid 1820
                                nPath = false;
11004 fschmid 1821
                                first = false;
14676 fschmid 1822
                                np4 = np;
3113 fschmid 1823
                        }
1824
                        np = points->point(poi);
1825
                        np1 = points->point(poi+1);
1826
                        np2 = points->point(poi+3);
1827
                        np3 = points->point(poi+2);
14676 fschmid 1828
                        if (np4 == np3)
1829
                                continue;
14777 fschmid 1830
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 6)
1831
                        if ((np == np1) && (np2 == np3))
1832
                                cairo_line_to( m_cr, np3.x(), np3.y());
1833
                        else
1834
#endif
11196 fschmid 1835
                                cairo_curve_to(m_cr, np1.x(), np1.y(), np2.x(), np2.y(), np3.x(), np3.y());
14676 fschmid 1836
                        np4 = np3;
3113 fschmid 1837
                }
1838
                if (closed)
1839
                cairo_close_path( m_cr );
1840
        }
638 fschmid 1841
}
1842
 
68 Franz 1843
void ScPainter::drawPolygon()
1844
{
1845
        fillPath();
1846
}
1847
 
1848
void ScPainter::drawPolyLine()
1849
{
1850
        strokePath();
1851
}
1852
 
1853
void ScPainter::drawLine(FPoint start, FPoint end)
1854
{
1855
        newPath();
1856
        moveTo(start.x(), start.y());
1857
        lineTo(end.x(), end.y());
1858
        strokePath();
1859
}
1860
 
1861
void ScPainter::drawRect(double x, double y, double w, double h)
1862
{
1863
        newPath();
12957 fschmid 1864
        cairo_rectangle(m_cr, x, y, w, h);
1865
//      moveTo( x, y );
1866
//      lineTo( x+w, y );
1867
//      lineTo( x+w, y+h );
1868
//      lineTo( x, y+h );
1869
//      lineTo( x, y );
1870
//      cairo_close_path( m_cr );
68 Franz 1871
        fillPath();
1872
        strokePath();
1873
}
12957 fschmid 1874
 
1875
void ScPainter::drawText(QRectF area, QString text)
1876
{
1877
        cairo_text_extents_t extents;
12959 fschmid 1878
        cairo_font_extents_t extentsF;
1879
        double x = area.center().x();
1880
        double y;
1881
        double ww = 0;
1882
        double hh = 0;
12957 fschmid 1883
        double r, g, b;
1884
        cairo_select_font_face(m_cr, m_font.family().toLatin1(), CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
1885
        cairo_set_font_size(m_cr, m_font.pointSizeF());
12959 fschmid 1886
        cairo_font_extents (m_cr, &extentsF);
1887
        QStringList textList = text.split("\n");
1888
        for (int a = 0; a < textList.count(); ++a)
1889
        {
1890
                cairo_text_extents (m_cr, textList[a].toUtf8(), &extents);
1891
                x = qMin(area.center().x() - (extents.width / 2.0 + extents.x_bearing), x);
1892
                ww = qMax(ww, extents.width);
1893
        }
1894
        hh = extentsF.height * textList.count();
1895
        y = area.center().y() - ((extentsF.height * textList.count()) / 2.0);
12957 fschmid 1896
        m_fill.getRgbF(&r, &g, &b);
1897
        cairo_set_source_rgba( m_cr, r, g, b, fill_trans );
1898
        cairo_new_path( m_cr );
12959 fschmid 1899
        cairo_rectangle(m_cr, x, y, ww, hh);
12957 fschmid 1900
        cairo_fill( m_cr );
1901
        cairo_new_path( m_cr );
12959 fschmid 1902
        y += extentsF.ascent;
12957 fschmid 1903
        cairo_move_to (m_cr, x, y);
1904
        m_stroke.getRgbF(&r, &g, &b);
1905
        cairo_set_source_rgba( m_cr, r, g, b, stroke_trans );
12959 fschmid 1906
        for (int a = 0; a < textList.count(); ++a)
1907
        {
1908
                cairo_show_text (m_cr, textList[a].toUtf8());
1909
                y += extentsF.height;
1910
                cairo_move_to (m_cr, x, y);
1911
        }
12957 fschmid 1912
}