Subversion Repositories Scribus

Rev

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