Subversion Repositories Scribus

Rev

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