Subversion Repositories Scribus

Rev

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

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