Subversion Repositories Scribus

Rev

Rev 7537 | Rev 7980 | 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
/* This file is part of the KDE project.
8
   Copyright (C) 2001, 2002, 2003 The Karbon Developers
9
 
10
   This library is free software; you can redistribute it and/or
11
   modify it under the terms of the GNU Library General Public
12
   License as published by the Free Software Foundation; either
13
   version 2 of the License, or (at your option) any later version.
14
 
15
   This library is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
   Library General Public License for more details.
19
 
20
   You should have received a copy of the GNU Library General Public License
21
   along with this library; see the file COPYING.LIB.  If not, write to
22
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23
   Boston, MA 02111-1307, USA.
24
*/
25
/* Adapted for Scribus 22.08.2003 by Franz Schmid */
26
// kopainter/libart wrapper
27
 
28
#include <qpaintdevice.h>
29
#include <qpixmap.h>
30
#include <qpointarray.h>
31
#include <qimage.h>
32
 
6733 avox 33
#include "scpainter.h"
34
 
3113 fschmid 35
#ifdef HAVE_CAIRO
5810 avox 36
        #include <cairo.h>
6128 fschmid 37
        #include "colorutil.h"
5688 jghali 38
        #if defined(_WIN32)
39
        #include <cairo-win32.h>
5810 avox 40
        #elif defined(Q_WS_X11)
5688 jghali 41
        #include <cairo-xlib.h>
5810 avox 42
        #elif defined(Q_WS_MAC)
6733 avox 43
//      #include <cairo-quartz.h>
5688 jghali 44
        #endif
7199 fschmid 45
// #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 1, 6)
5471 fschmid 46
        #include <cairo-svg.h>
7199 fschmid 47
// #endif
3113 fschmid 48
#else
5699 avox 49
// not HAVE_CAIRO
68 Franz 50
#include <libart_lgpl/art_vpath.h>
51
#include <libart_lgpl/art_bpath.h>
52
#include <libart_lgpl/art_vpath_bpath.h>
53
#include <libart_lgpl/art_svp_vpath.h>
54
#include <libart_lgpl/art_svp_vpath_stroke.h>
55
#include <libart_lgpl/art_svp.h>
56
#include <libart_lgpl/art_svp_ops.h>
57
#include <libart_lgpl/art_affine.h>
58
#include <libart_lgpl/art_svp_intersect.h>
59
#include <libart_lgpl/art_rect_svp.h>
60
#include <libart_lgpl/art_pathcode.h>
61
#include <libart_lgpl/art_vpath_dash.h>
62
#include <libart_lgpl/art_render_svp.h>
63
#include <libart_lgpl/art_vpath_svp.h>
3369 craig 64
#include "libart/art_render_misc.h"
65
#include "libart/art_rgb_svp.h"
66
#include "libart/art_render_pattern.h"
67
#include "libart/art_kmisc.h"
3113 fschmid 68
#define INITIAL_ALLOC   300
69
#define ALLOC_INCREMENT 100
70
#endif
68 Franz 71
 
1669 craig 72
#if defined(Q_WS_X11) && defined(SC_USE_PIXBUF)
68 Franz 73
#include <X11/Xlib.h>
5064 cbradney 74
#include "pixbuf/gdk-pixbuf-xlibrgb.h"
1669 craig 75
#endif
68 Franz 76
 
2686 craig 77
#if defined(_WIN32) && defined(SC_USE_GDI)
78
#include <windows.h>
79
#endif
80
 
5810 avox 81
#if defined(Q_WS_MAC) && defined(SC_USE_QUARTZ)
82
// #include ???
83
#endif
84
 
68 Franz 85
#include <math.h>
86
 
6733 avox 87
 
5699 avox 88
/// screen painter
1624 fschmid 89
ScPainter::ScPainter( QPaintDevice *target, unsigned int w, unsigned int h, unsigned int x, unsigned int y )
68 Franz 90
{
91
        m_target = target;
92
        m_width = w;
93
        m_height= h;
1624 fschmid 94
        m_x = x;
95
        m_y = y;
68 Franz 96
        m_buffer = 0L;
5699 avox 97
#ifdef HAVE_CAIRO
98
#else
68 Franz 99
        m_path = 0L;
6463 fschmid 100
        m_clipPath = 0L;
3113 fschmid 101
#endif
68 Franz 102
        m_index = 0;
103
        m_stroke = QColor(0,0,0);
104
        m_fill = QColor(0,0,0);
105
        fill_trans = 1.0;
106
        stroke_trans = 1.0;
107
        m_fillRule = true;
108
        fillMode = 1;
109
        LineWidth = 1.0;
110
        m_offset = 0;
111
        m_array.clear();
112
        mf_underline = false;
113
        mf_strikeout = false;
114
        mf_shadow = false;
115
        mf_outlined = false;
205 Franz 116
        PLineEnd = Qt::SquareCap;
117
        PLineJoin = Qt::RoundJoin;
68 Franz 118
        fill_gradient = VGradient(VGradient::linear);
119
        stroke_gradient = VGradient(VGradient::linear);
1669 craig 120
        m_zoomFactor = 1;
1815 fschmid 121
        imageMode = false;
3113 fschmid 122
        m_matrix = QWMatrix();
123
#ifdef HAVE_CAIRO
5373 fschmid 124
        layeredMode = false;
5471 fschmid 125
        svgMode = false;
5810 avox 126
        cairo_surface_t *img;
127
#ifdef Q_WS_X11
3113 fschmid 128
        pixm = QPixmap(w, h);
129
        Display *dpy = pixm.x11AppDisplay();
130
        Drawable drw = pixm.handle();
131
        img = cairo_xlib_surface_create(dpy, drw, (Visual*)pixm.x11Visual(), w, h);
5810 avox 132
#elif defined(_WIN32)
5688 jghali 133
        pixm = QPixmap(w, h, 32);
134
        img = cairo_win32_surface_create(pixm.handle());
5810 avox 135
#elif defined(SC_USE_QUARTZ)
136
        // ???
137
#else
138
        m_img.create(w, h, 32);
139
        img = cairo_image_surface_create_for_data(m_img.bits(), CAIRO_FORMAT_ARGB32, w, h, 4);
5688 jghali 140
#endif
3113 fschmid 141
        m_cr = cairo_create(img);
142
        clear();
143
        cairo_save( m_cr );
144
        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
3173 fschmid 145
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
3120 fschmid 146
/*      Setting to 0.5 here gives a good tradeoff between speed and precision
147
        the former setting of 0.2 is just too precise, and setting it to 0.9 or greater will give bad rendering */
148
        cairo_set_tolerance( m_cr, 0.5 );
5699 avox 149
#else 
150
        // not HAVE_CAIRO
151
#if defined(Q_WS_X11) && defined(SC_USE_PIXBUF)
3113 fschmid 152
        resize( m_width, m_height );
153
        clear();
1624 fschmid 154
        xlib_rgb_init_with_depth( target->x11Display(), XScreenOfDisplay( target->x11Display(), target->x11Screen() ), target->x11Depth() );
68 Franz 155
        gc = XCreateGC( target->x11Display(), target->handle(), 0, 0 );
2686 craig 156
#elif defined(_WIN32) && defined(SC_USE_GDI)
3113 fschmid 157
        resize( m_width, m_height );
158
        clear();
2686 craig 159
        dc = CreateCompatibleDC( target->handle() );
3175 avox 160
#else
161
        resize( m_width, m_height );
162
        clear();
1669 craig 163
#endif
5699 avox 164
#endif
68 Franz 165
}
166
 
5699 avox 167
/// std image painter
7537 fschmid 168
ScPainter::ScPainter( QImage *target, unsigned int w, unsigned int h, unsigned int x, unsigned int y )
1815 fschmid 169
{
170
        m_target = 0L;
171
        m_width = w;
172
        m_height= h;
173
        m_x = x;
174
        m_y = y;
175
        m_buffer = 0L;
3113 fschmid 176
        m_index = 0;
1815 fschmid 177
        m_stroke = QColor(0,0,0);
178
        m_fill = QColor(0,0,0);
179
        fill_trans = 1.0;
180
        stroke_trans = 1.0;
181
        m_fillRule = true;
182
        fillMode = 1;
183
        LineWidth = 1.0;
184
        m_offset = 0;
185
        m_array.clear();
186
        mf_underline = false;
187
        mf_strikeout = false;
188
        mf_shadow = false;
189
        mf_outlined = false;
190
        PLineEnd = Qt::SquareCap;
191
        PLineJoin = Qt::RoundJoin;
192
        fill_gradient = VGradient(VGradient::linear);
193
        stroke_gradient = VGradient(VGradient::linear);
194
        m_zoomFactor = 1;
195
        imageMode = true;
196
        m_image = target;
5260 fschmid 197
        m_matrix = QWMatrix();
3376 fschmid 198
#ifdef HAVE_CAIRO
5373 fschmid 199
        layeredMode = false;
5471 fschmid 200
        svgMode = false;
3376 fschmid 201
        cairo_surface_t *img = cairo_image_surface_create_for_data(target->bits(), CAIRO_FORMAT_ARGB32, w, h, w*4);
202
        m_cr = cairo_create(img);
203
        clear();
204
        cairo_save( m_cr );
205
        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
206
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
207
/*      Setting to 0.5 here gives a good tradeoff between speed and precision
208
        the former setting of 0.2 is just too precise, and setting it to 0.9 or greater will give bad rendering */
209
        cairo_set_tolerance( m_cr, 0.5 );
210
#else
211
        resize( m_width, m_height );
212
        clear();
213
        m_path = 0L;
6463 fschmid 214
        m_clipPath = 0L;
3376 fschmid 215
#endif
1815 fschmid 216
}
217
 
5373 fschmid 218
#ifdef HAVE_CAIRO
5699 avox 219
/// image painter
7537 fschmid 220
ScPainter::ScPainter( QImage *target, unsigned int w, unsigned int h, double transparency, int blendmode )
5373 fschmid 221
{
222
        m_target = 0L;
223
        m_width = w;
224
        m_height= h;
225
        m_buffer = 0L;
226
        m_index = 0;
227
        m_stroke = QColor(0,0,0);
228
        m_fill = QColor(0,0,0);
229
        fill_trans = 1.0;
230
        stroke_trans = 1.0;
231
        m_fillRule = true;
232
        fillMode = 1;
233
        LineWidth = 1.0;
234
        m_offset = 0;
235
        m_layerTransparency = transparency;
236
        m_blendMode = blendmode;
237
        m_array.clear();
238
        mf_underline = false;
239
        mf_strikeout = false;
240
        mf_shadow = false;
241
        mf_outlined = false;
242
        PLineEnd = Qt::SquareCap;
243
        PLineJoin = Qt::RoundJoin;
244
        fill_gradient = VGradient(VGradient::linear);
245
        stroke_gradient = VGradient(VGradient::linear);
246
        m_zoomFactor = 1;
247
        layeredMode = true;
248
        imageMode = true;
5471 fschmid 249
        svgMode = false;
5373 fschmid 250
        m_image = target;
251
        m_matrix = QWMatrix();
7199 fschmid 252
/*
5471 fschmid 253
#if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 1, 6)
5469 fschmid 254
        tmp_image = QImage(w, h, 32, QImage::BigEndian);
5373 fschmid 255
        tmp_image.fill( qRgba(255, 255, 255, 0) );
256
        cairo_surface_t *img = cairo_image_surface_create_for_data(tmp_image.bits(), CAIRO_FORMAT_ARGB32, w, h, w*4);
257
        m_cr = cairo_create(img);
258
        clear();
5471 fschmid 259
#else
7199 fschmid 260
*/
7537 fschmid 261
//      m_image->fill( qRgba(255, 255, 255, 0) );
5471 fschmid 262
        cairo_surface_t *img = cairo_image_surface_create_for_data(m_image->bits(), CAIRO_FORMAT_ARGB32, w, h, w*4);
263
        m_cr = cairo_create(img);
7199 fschmid 264
// #endif
5373 fschmid 265
        cairo_save( m_cr );
266
        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
267
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
268
        cairo_set_tolerance( m_cr, 0.5 );
269
}
5471 fschmid 270
 
7199 fschmid 271
// #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 1, 6)
5699 avox 272
/// SVG file painter
273
ScPainter::ScPainter( QString target, unsigned int w, unsigned int h,
274
                                          double transparency, int blendmode )
5471 fschmid 275
{
276
        m_target = 0L;
277
        m_width = w;
278
        m_height= h;
279
        m_buffer = 0L;
280
        m_index = 0;
281
        m_stroke = QColor(0,0,0);
282
        m_fill = QColor(0,0,0);
283
        fill_trans = 1.0;
284
        stroke_trans = 1.0;
285
        m_fillRule = true;
286
        fillMode = 1;
287
        LineWidth = 1.0;
288
        m_offset = 0;
289
        m_layerTransparency = transparency;
290
        m_blendMode = blendmode;
291
        m_array.clear();
292
        mf_underline = false;
293
        mf_strikeout = false;
294
        mf_shadow = false;
295
        mf_outlined = false;
296
        PLineEnd = Qt::SquareCap;
297
        PLineJoin = Qt::RoundJoin;
298
        fill_gradient = VGradient(VGradient::linear);
299
        stroke_gradient = VGradient(VGradient::linear);
300
        m_zoomFactor = 1;
301
        layeredMode = true;
302
        imageMode = false;
303
        svgMode = true;
304
        m_matrix = QWMatrix();
305
        cairo_surface_t *img = cairo_svg_surface_create(target, w, h);
306
        m_cr = cairo_create(img);
307
        cairo_save( m_cr );
308
        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
309
        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
310
        cairo_set_tolerance( m_cr, 0.5 );
311
}
7199 fschmid 312
// #endif
5699 avox 313
// HAVE_CAIRO
5471 fschmid 314
#endif
315
 
68 Franz 316
ScPainter::~ScPainter()
317
{
5699 avox 318
#ifdef HAVE_CAIRO
319
#else
68 Franz 320
        // If we are in target mode, we created a buffer, else if we used the other ctor
321
        // we didnt.
1815 fschmid 322
        if (( m_target ) || ( imageMode))
68 Franz 323
                art_free( m_buffer );
324
        if( m_path )
325
                art_free( m_path );
3113 fschmid 326
#endif
5699 avox 327
 
328
 
3113 fschmid 329
#ifdef HAVE_CAIRO
4447 fschmid 330
        cairo_surface_destroy(cairo_get_target(m_cr));
3113 fschmid 331
        cairo_destroy( m_cr );
5699 avox 332
#else
333
        // not HAVE_CAIRO
334
#if defined(Q_WS_X11) && defined(SC_USE_PIXBUF)
5471 fschmid 335
        if ((imageMode) || (svgMode))
3376 fschmid 336
                return;
68 Franz 337
        if( gc )
338
                XFreeGC( m_target->x11Display(), gc );
2686 craig 339
#elif defined(_WIN32) && defined(SC_USE_GDI)
5699 avox 340
        if (imageMode || svgMode)
3376 fschmid 341
                return;
2686 craig 342
        if( dc )
343
                DeleteDC( dc );
1669 craig 344
#endif
5699 avox 345
#endif
68 Franz 346
}
347
 
5373 fschmid 348
#ifdef HAVE_CAIRO
7049 fschmid 349
void ScPainter::beginLayer(double transparency, int blendmode, FPointArray *clipArray)
5373 fschmid 350
{
7199 fschmid 351
// #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 1, 6)
5604 fschmid 352
        layerProp la;
7199 fschmid 353
//      #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 1, 8)
5604 fschmid 354
        la.data = cairo_get_group_target(m_cr);
7199 fschmid 355
//      #endif
5604 fschmid 356
        la.blendmode = m_blendMode;
357
        la.tranparency = m_layerTransparency;
5373 fschmid 358
        m_layerTransparency = transparency;
359
        m_blendMode = blendmode;
7049 fschmid 360
        la.pushed = false;
361
        la.groupClip.resize(0);
362
        if (clipArray != NULL)
5604 fschmid 363
        {
7049 fschmid 364
                la.groupClip = *clipArray;
5604 fschmid 365
        }
7757 fschmid 366
//      if ((transparency != 1.0) || (blendmode != 0) || (clipArray != NULL))
367
//      {
7049 fschmid 368
                cairo_push_group(m_cr);
369
                la.pushed = true;
7757 fschmid 370
//      }
7049 fschmid 371
        Layers.push(la);
7199 fschmid 372
/*
5471 fschmid 373
#else
5373 fschmid 374
        tmp_image.fill( qRgba(255, 255, 255, 0) );
5471 fschmid 375
#endif
7199 fschmid 376
*/
5373 fschmid 377
}
378
 
7049 fschmid 379
void ScPainter::endLayer()
5373 fschmid 380
{
7049 fschmid 381
        layerProp la;
382
        la = Layers.top();
7199 fschmid 383
// #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 1, 6)
7049 fschmid 384
        if (la.pushed)
385
        {
7199 fschmid 386
//      #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 1, 8)
7077 fschmid 387
                if ((m_blendMode != 0) && (Layers.count() != 1))
5601 fschmid 388
                {
7077 fschmid 389
                        cairo_surface_t *tmp = cairo_get_group_target(m_cr);
390
                        cairo_surface_t *tmpB = Layers.top().data;
391
                        if ((tmp != NULL) && (tmpB != NULL))
5601 fschmid 392
                        {
7077 fschmid 393
                                if ((cairo_surface_get_type(tmp) == CAIRO_SURFACE_TYPE_IMAGE) && (cairo_surface_get_type(tmpB) == CAIRO_SURFACE_TYPE_IMAGE))
5601 fschmid 394
                                {
7077 fschmid 395
                                        cairo_surface_flush(tmp);
396
                                        int stride = cairo_image_surface_get_stride(tmp);
397
                                        unsigned char *s = cairo_image_surface_get_data(tmp);
398
                                        unsigned char *d = cairo_image_surface_get_data(tmpB);
399
                                        int h = cairo_image_surface_get_height(tmp);
400
                                        int w = cairo_image_surface_get_width(tmp);
401
                                        uint oldDst = 1;
402
                                        uint oldSrc = 2;
403
                                        uint newResult = 0;
404
                                        bool first = true;
7175 fschmid 405
                                        QRgb *src;
406
                                        QRgb *dst;
407
                                        uchar src_a, src_r, src_g, src_b, dst_a, dst_r, dst_g, dst_b, new_r, new_g, new_b;
7077 fschmid 408
                                        for( int yi=0; yi < h; ++yi )
5601 fschmid 409
                                        {
7175 fschmid 410
                                                dst = (QRgb*)d;
411
                                                src = (QRgb*)s;
7077 fschmid 412
                                                for( int xi=0; xi < w; ++xi )
5601 fschmid 413
                                                {
7175 fschmid 414
                                                        src_r = qRed(*src);
415
                                                        src_g = qGreen(*src);
416
                                                        src_b = qBlue(*src);
417
                                                        src_a = qAlpha(*src);
418
                                                        dst_r = qRed(*dst);
419
                                                        dst_g = qGreen(*dst);
420
                                                        dst_b = qBlue(*dst);
421
                                                        dst_a = qAlpha(*dst);
7077 fschmid 422
                                                        if ((src_a > 0) && (dst_a > 0))
5601 fschmid 423
                                                        {
7077 fschmid 424
                                                                if (((*dst) != oldDst) || ((*src) != oldSrc) || (first))
6505 fschmid 425
                                                                {
7077 fschmid 426
                                                                        if (m_blendMode == 1)
427
                                                                        {
428
                                                                                src_r = dst_r  < src_r ? dst_r  : src_r;
429
                                                                                src_g = dst_g < src_g ? dst_g : src_g;
430
                                                                                src_b = dst_b < src_b ? dst_b : src_b;
431
                                                                        }
432
                                                                        else if (m_blendMode == 2)
433
                                                                        {
434
                                                                                src_r = dst_r  < src_r ? src_r : dst_r;
435
                                                                                src_g = dst_g < src_g ? src_g : dst_g;
436
                                                                                src_b = dst_b < src_b ? src_b : dst_b;
437
                                                                        }
438
                                                                        else if (m_blendMode == 3)
439
                                                                        {
440
                                                                                src_r = INT_MULT(src_r, dst_r);
441
                                                                                src_g = INT_MULT(src_g, dst_g);
442
                                                                                src_b = INT_MULT(src_b, dst_b);
443
                                                                        }
444
                                                                        else if (m_blendMode == 4)
445
                                                                        {
446
                                                                                src_r = 255 - ((255-src_r) * (255-dst_r) / 128);
447
                                                                                src_g = 255 - ((255-src_g) * (255-dst_g) / 128);
448
                                                                                src_b = 255 - ((255-src_b) * (255-dst_b) / 128);
449
                                                                        }
450
                                                                        else if (m_blendMode == 5)
451
                                                                        {
452
                                                                                src_r = dst_r < 128 ? src_r * dst_r / 128 : 255 - ((255-src_r) * (255-dst_r) / 128);
453
                                                                                src_g = dst_g < 128 ? src_g * dst_g / 128 : 255 - ((255-src_g) * (255-dst_g) / 128);
454
                                                                                src_b = dst_b < 128 ? src_b * dst_b / 128 : 255 - ((255-src_b) * (255-dst_b) / 128);
455
                                                                        }
456
                                                                        else if (m_blendMode == 6)
457
                                                                        {
458
                                                                                src_r = src_r < 128 ? src_r * dst_r / 128 : 255 - ((255-src_r) * (255-dst_r) / 128);
459
                                                                                src_g = src_g < 128 ? src_g * dst_g / 128 : 255 - ((255-src_g) * (255-dst_g) / 128);
460
                                                                                src_b = src_b < 128 ? src_b * dst_b / 128 : 255 - ((255-src_b) * (255-dst_b) / 128);
461
                                                                        }
462
                                                                        else if (m_blendMode == 7)
463
                                                                        {
464
                                                                                float s_r = (255 - src_r) / 255.0;
465
                                                                                float s_g = (255 - src_g) / 255.0;
466
                                                                                float s_b = (255 - src_b) / 255.0;
467
                                                                                float d_r = (255 - dst_r) / 255.0;
468
                                                                                float d_g = (255 - dst_g) / 255.0;
469
                                                                                float d_b = (255 - dst_b) / 255.0;
470
                                                                                float dzr = d_r > 0.25 ? sqrt(d_r) : ((16 * d_r - 12) * d_r + 4) * d_r;
471
                                                                                float dzg = d_g > 0.25 ? sqrt(d_g) : ((16 * d_g - 12) * d_g + 4) * d_g;
472
                                                                                float dzb = d_b > 0.25 ? sqrt(d_b) : ((16 * d_b - 12) * d_b + 4) * d_b;
473
                                                                                s_r = s_r <= 0.5 ? d_r - (1 - 2 * s_r) * d_r * (1 - d_r) : d_r + (2 * s_r - 1) * (dzr  - d_r);
474
                                                                                s_g = s_g <= 0.5 ? d_g - (1 - 2 * s_g) * d_g * (1 - d_g) : d_g + (2 * s_g - 1) * (dzg  - d_g);
475
                                                                                s_b = s_b <= 0.5 ? d_b - (1 - 2 * s_b) * d_b * (1 - d_b) : d_b + (2 * s_b - 1) * (dzb  - d_b);
476
                                                                                src_r = 255 - qRound(s_r * 255);
477
                                                                                src_g = 255 - qRound(s_g * 255);
478
                                                                                src_b = 255 - qRound(s_b * 255);
479
                                                                        }
480
                                                                        else if (m_blendMode == 8)
481
                                                                        {
482
                                                                                src_r = dst_r > src_r ? dst_r - src_r : src_r - dst_r;
483
                                                                                src_g = dst_g > src_g ? dst_g - src_g : src_g - dst_g;
484
                                                                                src_b = dst_b > src_b ? dst_b - src_b : src_b - dst_b;
485
                                                                        }
486
                                                                        else if (m_blendMode == 9)
487
                                                                        {
488
                                                                                src_r = dst_r + src_r - src_r * dst_r / 128;
489
                                                                                src_g = dst_g + src_g - src_g * dst_g / 128;
490
                                                                                src_b = dst_b + src_b - src_b * dst_b / 128;
491
                                                                        }
492
                                                                        else if (m_blendMode == 10)
493
                                                                        {
494
                                                                                src_r = src_r == 255 ? QMIN(255, dst_r * 256) : QMIN(255, ((dst_r * 256) / (255-src_r)));
495
                                                                                src_g = src_g == 255 ? QMIN(255, dst_g * 256) : QMIN(255, ((dst_g * 256) / (255-src_g)));
496
                                                                                src_b = src_b == 255 ? QMIN(255, dst_b * 256) : QMIN(255, ((dst_b * 256) / (255-src_b)));
497
                                                                        }
498
                                                                        else if (m_blendMode == 11)
499
                                                                        {
500
                                                                                src_r = QMAX(1, src_r);
501
                                                                                src_g = QMAX(1, src_g);
502
                                                                                src_b = QMAX(1, src_b);
503
                                                                                src_r = static_cast<int>(255 - (((255-dst_r) * 256) / src_r)) < 0 ? 0 : 255 - (((255-dst_r) * 256) / src_r);
504
                                                                                src_g = static_cast<int>(255 - (((255-dst_g) * 256) / src_g)) < 0 ? 0 : 255 - (((255-dst_g) * 256) / src_g);
505
                                                                                src_b = static_cast<int>(255 - (((255-dst_b) * 256) / src_b)) < 0 ? 0 : 255 - (((255-dst_b) * 256) / src_b);
506
                                                                        }
507
        //                                                      else if (m_blendMode == 12)
508
        //                                                      {
509
                        /*                                              This code is a blendmode that simulates the effect of overprinting
510
                                                                        Works by converting source and destination colour to CMYK and adding them together
511
                                                                        Finally the result is converted back to RGB */
512
        /*                                                              int K1 = QMIN(QMIN(255 - src_r, 255 - src_g), 255 - src_b);
513
                                                                        int K2 = QMIN(QMIN(255 - dst_r, 255 - dst_g), 255 - dst_b);
514
                                                                        int C = QMIN(QMIN(255 - src_r - K1, 255) + QMIN(255 - dst_r - K2, 255), 255);
515
                                                                        int M = QMIN(QMIN(255 - src_g - K1, 255) + QMIN(255 - dst_g - K2, 255), 255) ;
516
                                                                        int Y = QMIN(QMIN(255 - src_b - K1, 255) + QMIN(255 - dst_b - K2, 255), 255) ;
517
                                                                        int K = QMIN(K1 + K2, 255);
518
                                                                        src_r = 255 - QMIN(255, C + K);
519
                                                                        src_g = 255 - QMIN(255, M + K);
520
                                                                        src_b = 255 - QMIN(255, Y+ K);
521
                                                                } */
522
                                                                        else if (m_blendMode == 12)
523
                                                                        {
7175 fschmid 524
                                                                                new_r = dst_r;
525
                                                                                new_g = dst_g;
526
                                                                                new_b = dst_b;
7077 fschmid 527
                                                                                RGBTOHSV(src_r, src_g, src_b);
528
                                                                                RGBTOHSV(new_r, new_g, new_b);
529
                                                                                new_r = src_r;
530
                                                                                HSVTORGB(new_r, new_g, new_b);
531
                                                                                src_r = new_r;
532
                                                                                src_g = new_g;
533
                                                                                src_b = new_b;
534
                                                                        }
535
                                                                        else if (m_blendMode == 13)
536
                                                                        {
7175 fschmid 537
                                                                                new_r = dst_r;
538
                                                                                new_g = dst_g;
539
                                                                                new_b = dst_b;
7077 fschmid 540
                                                                                RGBTOHSV(src_r, src_g, src_b);
541
                                                                                RGBTOHSV(new_r, new_g, new_b);
542
                                                                                new_g = src_g;
543
                                                                                HSVTORGB(new_r, new_g, new_b);
544
                                                                                src_r = new_r;
545
                                                                                src_g = new_g;
546
                                                                                src_b = new_b;
547
                                                                        }
548
                                                                        else if (m_blendMode == 14)
549
                                                                        {
7175 fschmid 550
                                                                                new_r = dst_r;
551
                                                                                new_g = dst_g;
552
                                                                                new_b = dst_b;
7077 fschmid 553
                                                                                RGBTOHLS(src_r, src_g, src_b);
554
                                                                                RGBTOHLS(new_r, new_g, new_b);
555
                                                                                new_r = src_r;
556
                                                                                new_b = src_b;
557
                                                                                HLSTORGB(new_r, new_g, new_b);
558
                                                                                src_r = new_r;
559
                                                                                src_g = new_g;
560
                                                                                src_b = new_b;
561
                                                                        }
562
                                                                        else if (m_blendMode == 15)
563
                                                                        {
7175 fschmid 564
                                                                                new_r = dst_r;
565
                                                                                new_g = dst_g;
566
                                                                                new_b = dst_b;
7077 fschmid 567
                                                                                RGBTOHSV(src_r, src_g, src_b);
568
                                                                                RGBTOHSV(new_r, new_g, new_b);
569
                                                                                new_b = src_b;
570
                                                                                HSVTORGB(new_r, new_g, new_b);
571
                                                                                src_r = new_r;
572
                                                                                src_g = new_g;
573
                                                                                src_b = new_b;
574
                                                                        }
575
                                                                        newResult = qRgba(src_r, src_g, src_b, src_a);
576
                                                                        oldDst = (*dst);
577
                                                                        oldSrc = (*src);
578
                                                                        first = false;
6505 fschmid 579
                                                                }
7077 fschmid 580
                                                                (*src) = newResult;
5601 fschmid 581
                                                        }
7077 fschmid 582
                                                        src++;
583
                                                        dst++;
5601 fschmid 584
                                                }
7077 fschmid 585
                                                s += stride;
586
                                                d += stride;
5601 fschmid 587
                                        }
7077 fschmid 588
                                        cairo_surface_mark_dirty(tmp);
5601 fschmid 589
                                }
590
                        }
591
                }
7199 fschmid 592
//              #endif
5601 fschmid 593
        }
5604 fschmid 594
        la = Layers.pop();
7049 fschmid 595
        if (la.pushed)
6451 fschmid 596
        {
7049 fschmid 597
                cairo_pop_group_to_source (m_cr);
598
                if (la.groupClip.size() != 0)
599
                {
600
                        setupPolygon(&la.groupClip);
601
                        setClipPath();
602
                }
603
                if (m_blendMode == 0)
604
                {
605
                        cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
606
                        cairo_paint_with_alpha (m_cr, m_layerTransparency);
607
                }
608
                else
609
                {
610
                        cairo_set_operator(m_cr, CAIRO_OPERATOR_DEST_OUT);
611
                        cairo_paint_with_alpha (m_cr, m_layerTransparency);
612
                        cairo_set_operator(m_cr, CAIRO_OPERATOR_ADD);
613
                        cairo_paint_with_alpha (m_cr, m_layerTransparency);
614
                }
5637 fschmid 615
                cairo_set_operator(m_cr, CAIRO_OPERATOR_OVER);
616
        }
5604 fschmid 617
        m_layerTransparency = la.tranparency;
618
        m_blendMode = la.blendmode;
7199 fschmid 619
/*
5471 fschmid 620
#else
5373 fschmid 621
        cairo_surface_flush(cairo_get_target(m_cr));
622
        int words = m_image->numBytes() / 4;
623
        QRgb *s = (QRgb*)(tmp_image.bits());
624
        QRgb *d = (QRgb*)(m_image->bits());
7175 fschmid 625
        QRgb src, dst;
626
        uchar src_a, src_r, src_g, src_b, dst_a, dst_r, dst_g, dst_b;
627
        int layOpa;
5373 fschmid 628
        for(int x = 0; x < words; ++x )
629
        {
7175 fschmid 630
                src = (*s);
631
                dst = (*d);
632
                src_a = qAlpha(src);
5469 fschmid 633
                if (src_a > 0)
5373 fschmid 634
                {
7175 fschmid 635
                        src_r = qRed(src);
636
                        src_g = qGreen(src);
637
                        src_b = qBlue(src);
638
                        dst_a = qAlpha(dst);
639
                        dst_r = qRed(dst);
640
                        dst_g = qGreen(dst);
641
                        dst_b = qBlue(dst);
642
                        layOpa = qRound(255 * m_layerTransparency);
5433 fschmid 643
                        src_a = INT_MULT(src_a, layOpa);
5469 fschmid 644
                        if ((dst_a > 0) && (src_a > 0))
5433 fschmid 645
                                (*d) = qRgba((dst_r * (255 - layOpa) + src_r * layOpa) / 255, (dst_g * (255 - layOpa) + src_g * layOpa) / 255, (dst_b * (255 - layOpa) + src_b * layOpa) / 255, dst_a + INT_MULT(255 - dst_a, src_a));
5469 fschmid 646
                        else if (src_a > 0)
5433 fschmid 647
                                (*d) = qRgba(src_r, src_g, src_b, src_a);
5373 fschmid 648
                }
649
                s++;
650
                d++;
651
        }
5471 fschmid 652
#endif
7199 fschmid 653
*/
5373 fschmid 654
}
5699 avox 655
//HAVE_CAIRO
5373 fschmid 656
#endif
657
 
68 Franz 658
void ScPainter::begin()
659
{
660
}
661
 
662
void ScPainter::end()
663
{
5373 fschmid 664
#ifdef HAVE_CAIRO
5471 fschmid 665
        if (svgMode)
666
                cairo_show_page (m_cr);
5373 fschmid 667
        if (layeredMode)
668
        {
7199 fschmid 669
/*
5471 fschmid 670
#if CAIRO_VERSION < CAIRO_VERSION_ENCODE(1, 1, 6)
5373 fschmid 671
                endLayer();
5471 fschmid 672
#endif
7199 fschmid 673
*/
5433 fschmid 674
                cairo_surface_flush(cairo_get_target(m_cr));
5373 fschmid 675
                cairo_restore( m_cr );
676
                return;
677
        }
678
#endif
1815 fschmid 679
        if (imageMode)
680
        {
3376 fschmid 681
#ifdef HAVE_CAIRO
682
                cairo_surface_flush(cairo_get_target(m_cr));
683
                cairo_restore( m_cr );
684
#else
1815 fschmid 685
                QRgb * bits = (QRgb *) m_image->bits();
686
                int words = m_image->numBytes() / 4;
687
                art_u8 * p = m_buffer;;
688
                for (int i=0; i < words; ++i)
689
                {
690
                        art_u8 r = *p++;
691
                        art_u8 g = *p++;
692
                        art_u8 b = *p++;
693
                        art_u8 a = *p++;
694
                        *bits++ = qRgba(r,g,b,a);
695
                }
3113 fschmid 696
#endif
1815 fschmid 697
        }
698
        else
699
        {
3113 fschmid 700
#ifdef HAVE_CAIRO
701
                cairo_surface_flush(cairo_get_target(m_cr));
5810 avox 702
#ifdef Q_WS_X11
3113 fschmid 703
                bitBlt( m_target, m_x, m_y, &pixm, 0, 0, m_width, m_height );
5810 avox 704
#elif defined(_WIN32)
705
                bitBlt( m_target, m_x, m_y, &pixm, 0, 0, m_width, m_height );
706
#elif defined(SC_USE_QUARTZ)
707
                // ???
708
#else
709
                bitBlt( m_target, m_x, m_y, &m_img, 0, 0, m_width, m_height );
710
#endif
3113 fschmid 711
                cairo_restore( m_cr );
5699 avox 712
#else
713
                // not HAVE_CAIRO
714
  #if defined(Q_WS_X11) && defined(SC_USE_PIXBUF)
1815 fschmid 715
                // Use the original gdk-pixbuf based bitblit on X11
716
                xlib_draw_rgb_32_image( m_target->handle(), gc, m_x, m_y, m_width, m_height, XLIB_RGB_DITHER_NONE, m_buffer, m_width * 4 );
5699 avox 717
  #elif defined(_WIN32) && defined(SC_USE_GDI)
2686 craig 718
                // Use Win32 implementation
719
                BITMAPINFO bmpInfo;
720
                BITMAPINFOHEADER *bmpHeader;
721
                long* bmpData;
722
 
723
                bmpHeader = &(bmpInfo.bmiHeader);
724
                bmpHeader->biSize = sizeof(BITMAPINFOHEADER);
725
                bmpHeader->biWidth = m_width;
726
                bmpHeader->biHeight = -m_height;
727
                bmpHeader->biPlanes = 1;
728
                bmpHeader->biBitCount = 32;
729
                bmpHeader->biCompression = BI_RGB;
730
                bmpHeader->biSizeImage = 0; // Valid only if biCompression = BI_RGB
731
                bmpHeader->biXPelsPerMeter = 0;
732
                bmpHeader->biYPelsPerMeter = 0;
733
                bmpHeader->biClrUsed = 0;
734
                bmpHeader->biClrImportant = 0;
735
 
736
                // Create a device independent Bitmap
737
                HBITMAP hBmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, (void** ) (&bmpData), NULL, NULL);
738
                art_u8 * p = m_buffer;
739
                art_u8 r, g, b, a;
740
                int words = m_width * m_height; // Valid only if biBitCount = 32
741
 
742
                for (int i = 0; i < words; ++i) {
743
                        r = *p++;
744
                        g = *p++;
745
                        b = *p++;
746
                        a = *p++;
747
                        *bmpData++ = ( (a << 24) + (r << 16) + (g << 8) + b);
748
                }
749
 
750
                HGDIOBJ obj = SelectObject( dc, hBmp);
751
                BitBlt( m_target->handle() , m_x, m_y, m_width, m_height, dc, 0, 0, SRCCOPY);
752
                SelectObject( dc, obj);
753
                DeleteObject( hBmp );
5699 avox 754
  #else
1815 fschmid 755
                // Portable copying onto the canvas with no X11 dependency by Andreas Vox
756
                QImage qimg(m_width, m_height, 32, QImage::BigEndian);
757
                QRgb * bits = (QRgb *) qimg.bits();
758
                int words = qimg.numBytes() / 4;
759
                art_u8 * p = m_buffer;;
760
                for (int i=0; i < words; ++i) {
761
                        art_u8 r = *p++;
762
                        art_u8 g = *p++;
763
                        art_u8 b = *p++;
764
                        art_u8 a = *p++;
765
                        *bits++ = qRgba(r,g,b,a);
766
                }
767
                bitBlt(m_target, m_x, m_y, &qimg);
5699 avox 768
  #endif
1815 fschmid 769
#endif
1669 craig 770
        }
68 Franz 771
}
772
 
1624 fschmid 773
void ScPainter::clear()
68 Franz 774
{
3113 fschmid 775
#ifdef HAVE_CAIRO
3376 fschmid 776
        if (imageMode)
777
                m_image->fill( qRgba(255, 255, 255, 255) );
5810 avox 778
        else {
779
                if (! m_img.isNull())
780
                        m_img.fill( qRgba(255, 255, 255, 255) );
781
                else
782
                        pixm.fill( Qt::white );
783
        }
3113 fschmid 784
#else
68 Franz 785
        if( m_buffer )
214 Franz 786
                memset( m_buffer, 255, m_width * m_height * 4 );
3113 fschmid 787
#endif
68 Franz 788
}
789
 
1624 fschmid 790
void ScPainter::clear( const QColor &c )
68 Franz 791
{
3113 fschmid 792
#ifdef HAVE_CAIRO
3376 fschmid 793
        QRgb cs = c.rgb();
794
        if (imageMode)
795
                m_image->fill( qRgba(qRed(cs), qGreen(cs), qBlue(cs), qAlpha(cs)) );
5810 avox 796
        else {
797
                if (!m_img.isNull())
798
                        m_img.fill( qRgba(qRed(cs), qGreen(cs), qBlue(cs), qAlpha(cs)) );
799
                else
800
                        pixm.fill( c );
801
        }
3113 fschmid 802
#else
68 Franz 803
        if( m_buffer )
214 Franz 804
        {
805
                unsigned int *src = (unsigned int*)m_buffer;
806
                unsigned int co = qRgba(c.blue(), c.green(),  c.red(), 255);
807
                for(unsigned int cc = 0; cc < (m_width * m_height); ++cc)
808
                {
809
                        *src++ = co;
810
                }
811
        }
3113 fschmid 812
#endif
68 Franz 813
}
814
 
3113 fschmid 815
const QWMatrix ScPainter::worldMatrix()
816
{
817
#ifdef HAVE_CAIRO
818
        cairo_matrix_t matrix;
819
        cairo_get_matrix(m_cr, &matrix);
820
        QWMatrix mat;
821
        mat.setMatrix ( matrix.xx, matrix.yx, matrix.xy, matrix.yy, matrix.x0, matrix.y0 );
822
        return mat;
823
#else
824
        return m_matrix;
825
#endif
826
}
827
 
68 Franz 828
void ScPainter::setWorldMatrix( const QWMatrix &mat )
829
{
3113 fschmid 830
#ifdef HAVE_CAIRO
831
        cairo_matrix_t matrix;
832
        cairo_matrix_init(&matrix, mat.m11(), mat.m12(), mat.m21(), mat.m22(), mat.dx(), mat.dy());
833
        cairo_set_matrix(m_cr, &matrix);
834
#else
68 Franz 835
        m_matrix = mat;
3113 fschmid 836
#endif
68 Franz 837
}
838
 
6809 fschmid 839
#ifdef HAVE_CAIRO
840
void ScPainter::setAntialiasing(bool enable)
841
{
842
        if (enable)
843
                cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_DEFAULT);
844
        else
845
                cairo_set_antialias(m_cr, CAIRO_ANTIALIAS_NONE);
846
}
847
#endif
848
 
68 Franz 849
void ScPainter::setZoomFactor( double zoomFactor )
850
{
851
        m_zoomFactor = zoomFactor;
7141 fschmid 852
#ifdef HAVE_CAIRO
853
        cairo_scale (m_cr, m_zoomFactor, m_zoomFactor);
854
#endif
68 Franz 855
}
856
 
857
void ScPainter::translate( double x, double y )
858
{
3113 fschmid 859
#ifdef HAVE_CAIRO
860
        cairo_translate (m_cr, x, y);
861
#else
68 Franz 862
        m_matrix.translate(x, y);
3113 fschmid 863
#endif
68 Franz 864
}
865
 
866
void ScPainter::rotate( double r )
867
{
3113 fschmid 868
#ifdef HAVE_CAIRO
869
        cairo_rotate (m_cr, r * 3.1415927 / 180.0);
870
#else
68 Franz 871
        m_matrix.rotate(r);
3113 fschmid 872
#endif
68 Franz 873
}
874
 
875
void ScPainter::scale( double x, double y )
876
{
3113 fschmid 877
#ifdef HAVE_CAIRO
878
        cairo_scale (m_cr, x, y);
879
#else
68 Franz 880
        m_matrix.scale(x, y);
3113 fschmid 881
#endif
68 Franz 882
}
883
 
884
void ScPainter::moveTo( const double &x, const double &y )
885
{
3113 fschmid 886
#ifdef HAVE_CAIRO
7141 fschmid 887
        cairo_move_to( m_cr, x, y);
3113 fschmid 888
#else
68 Franz 889
        ensureSpace( m_index + 1 );
890
        m_path[ m_index ].code = ART_MOVETO;
891
        m_path[ m_index ].x3 = x * m_zoomFactor;
892
        m_path[ m_index ].y3 = y * m_zoomFactor;
893
        m_index++;
3113 fschmid 894
#endif
68 Franz 895
}
896
 
4646 subik 897
void
68 Franz 898
ScPainter::lineTo( const double &x, const double &y )
899
{
3113 fschmid 900
#ifdef HAVE_CAIRO
7141 fschmid 901
        cairo_line_to( m_cr, x, y);
3113 fschmid 902
#else
68 Franz 903
        ensureSpace( m_index + 1 );
904
        m_path[ m_index ].code = ART_LINETO;
905
        m_path[ m_index ].x3    = x * m_zoomFactor;
906
        m_path[ m_index ].y3    = y * m_zoomFactor;
907
        m_index++;
3113 fschmid 908
#endif
68 Franz 909
}
910
 
911
void ScPainter::curveTo( FPoint p1, FPoint p2, FPoint p3 )
912
{
3113 fschmid 913
#ifdef HAVE_CAIRO
7141 fschmid 914
        cairo_curve_to(m_cr, p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y());
3113 fschmid 915
#else
68 Franz 916
        ensureSpace( m_index + 1 );
917
        m_path[ m_index ].code = ART_CURVETO;
86 Franz 918
        m_path[ m_index ].x1    = p1.x() * m_zoomFactor;
919
        m_path[ m_index ].y1    = p1.y() * m_zoomFactor;
920
        m_path[ m_index ].x2    = p2.x() * m_zoomFactor;
921
        m_path[ m_index ].y2    = p2.y() * m_zoomFactor;
922
        m_path[ m_index ].x3    = p3.x() * m_zoomFactor;
923
        m_path[ m_index ].y3    = p3.y() * m_zoomFactor;
68 Franz 924
        m_index++;
3113 fschmid 925
#endif
68 Franz 926
}
927
 
928
void ScPainter::newPath()
929
{
3113 fschmid 930
#ifdef HAVE_CAIRO
931
        cairo_new_path( m_cr );
932
#else
68 Franz 933
        m_index = 0;
3113 fschmid 934
#endif
68 Franz 935
}
936
 
5233 fschmid 937
void ScPainter::closePath()
938
{
939
#ifdef HAVE_CAIRO
940
        cairo_close_path( m_cr );
941
#else
942
        ensureSpace( m_index + 1 );
943
        m_path[ m_index ].code = ART_END;
944
        m_index++;
945
#endif
946
}
947
 
68 Franz 948
void ScPainter::setFillRule( bool fillRule )
949
{
950
        m_fillRule = fillRule;
951
}
952
 
953
void ScPainter::setFillMode( int fill )
954
{
955
        fillMode = fill;
956
}
957
 
958
void ScPainter::setGradient(VGradient::VGradientType mode, FPoint orig, FPoint vec, FPoint foc)
959
{
960
        fill_gradient.setType(mode);
961
        fill_gradient.setOrigin(orig);
962
        fill_gradient.setVector(vec);
963
        fill_gradient.setFocalPoint(foc);
964
}
965
 
1998 fschmid 966
void ScPainter::fillTextPath()
967
{
3113 fschmid 968
#ifdef HAVE_CAIRO
969
        drawVPath( 0 );
970
#else
1998 fschmid 971
        ArtVpath *path = art_bez_path_to_vec( m_path , 0.25 );
972
        drawVPath( path, 0, true );
3113 fschmid 973
#endif
1998 fschmid 974
}
975
 
976
void ScPainter::strokeTextPath()
977
{
978
        if( LineWidth == 0 )
979
                return;
3113 fschmid 980
#ifdef HAVE_CAIRO
981
        drawVPath( 1 );
982
#else
1998 fschmid 983
        ArtVpath *path = art_bez_path_to_vec( m_path , 0.25 );
984
        drawVPath( path, 1, true );
3113 fschmid 985
#endif
1998 fschmid 986
}
987
 
68 Franz 988
void ScPainter::fillPath()
989
{
3113 fschmid 990
#ifdef HAVE_CAIRO
991
        if( fillMode != 0)
992
                drawVPath( 0 );
993
#else
4646 subik 994
        if( m_index == 0 )
1998 fschmid 995
                return;
68 Franz 996
        if( fillMode != 0)
384 Franz 997
        {
68 Franz 998
                ArtVpath *path = art_bez_path_to_vec( m_path , 0.25 );
999
                drawVPath( path, 0 );
384 Franz 1000
        }
3113 fschmid 1001
#endif
68 Franz 1002
}
1003
 
1004
void ScPainter::strokePath()
1005
{
3113 fschmid 1006
        if( LineWidth == 0 )
1007
                return;
1008
#ifdef HAVE_CAIRO
1009
        drawVPath( 1 );
1010
#else
68 Franz 1011
        if( m_index == 0 )
1012
                return;
1013
        if( m_path[ m_index ].code != ART_END)
1014
                m_path[ m_index ].code = ART_END;
1015
        ArtVpath *path = art_bez_path_to_vec( m_path , 0.25 );
1016
        drawVPath( path, 1 );
3113 fschmid 1017
#endif
68 Franz 1018
}
1019
 
1020
QColor ScPainter::pen()
1021
{
1022
        return m_stroke;
1023
}
1024
 
1025
QColor ScPainter::brush()
1026
{
1027
        return m_fill;
1028
}
1029
 
1030
void ScPainter::setPen( const QColor &c )
1031
{
1032
        m_stroke = c;
1033
}
1034
 
80 Franz 1035
void ScPainter::setPen( const QColor &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
68 Franz 1036
{
1037
        m_stroke = c;
1038
        LineWidth = w;
1039
        PLineEnd = ca;
1040
        PLineJoin = jo;
80 Franz 1041
        double Dt = QMAX(2*w, 1);
1042
        double Da = QMAX(6*w, 1);
1043
        QValueList<double> tmp;
68 Franz 1044
        m_array.clear();
1045
        m_offset = 0;
1046
        switch (st)
1047
                {
1048
                case Qt::SolidLine:
1049
                        break;
1050
                case Qt::DashLine:
1051
                        m_array.append(Da);
1052
                        m_array.append(Dt);
1053
                        break;
1054
                case Qt::DotLine:
1055
                        m_array.append(Dt);
1056
                        break;
1057
                case Qt::DashDotLine:
1058
                        m_array.append(Da);
1059
                        m_array.append(Dt);
1060
                        m_array.append(Dt);
1061
                        m_array.append(Dt);
1062
                        break;
1063
                case Qt::DashDotDotLine:
1064
                        m_array.append(Da);
1065
                        m_array.append(Dt);
1066
                        m_array.append(Dt);
1067
                        m_array.append(Dt);
1068
                        m_array.append(Dt);
1069
                        m_array.append(Dt);
1070
                        break;
1071
                default:
1072
                        break;
1073
                }
1074
}
1075
 
80 Franz 1076
void ScPainter::setLineWidth( double w )
68 Franz 1077
{
1078
        LineWidth = w;
1079
}
1080
 
80 Franz 1081
void ScPainter::setPenOpacity( double op )
68 Franz 1082
{
1083
        stroke_trans = op;
1084
}
1085
 
1086
 
80 Franz 1087
void ScPainter::setDash(const QValueList<double>& array, double ofs)
68 Franz 1088
{
1089
        m_array = array;
1090
        m_offset = ofs;
1091
}
1092
 
1093
void ScPainter::setBrush( const QColor &c )
1094
{
1095
        m_fill = c;
1096
}
1097
 
80 Franz 1098
void ScPainter::setBrushOpacity( double op )
68 Franz 1099
{
1100
        fill_trans = op;
1101
}
1102
 
80 Franz 1103
void ScPainter::setOpacity( double op )
68 Franz 1104
{
1105
        fill_trans = op;
1106
        stroke_trans = op;
1107
}
1108
 
1109
void ScPainter::setFont( const QFont &f)
1110
{
1111
        m_font = f;
1112
}
1113
 
1114
QFont ScPainter::font()
1115
{
1116
        return m_font;
1117
}
1118
 
1119
void ScPainter::save()
1120
{
3113 fschmid 1121
#ifdef HAVE_CAIRO
1122
        cairo_save( m_cr );
1123
#else
68 Franz 1124
        MStack.push(m_matrix);
3113 fschmid 1125
#endif
68 Franz 1126
}
1127
 
1128
void ScPainter::restore()
1129
{
3113 fschmid 1130
#ifdef HAVE_CAIRO
1131
        cairo_restore( m_cr );
1132
#else
68 Franz 1133
        m_matrix = MStack.pop();
3113 fschmid 1134
#endif
68 Franz 1135
}
1136
 
3240 fschmid 1137
void ScPainter::setRasterOp( int   )
68 Franz 1138
{
1139
}
1140
 
6414 fschmid 1141
void ScPainter::setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation)
6368 fschmid 1142
{
6369 fschmid 1143
        m_pattern = pattern;
6414 fschmid 1144
        patternScaleX = scaleX / 100.0;
1145
        patternScaleY = scaleY / 100.0;
1146
        patternOffsetX = offsetX;
1147
        patternOffsetY = offsetY;
1148
        patternRotation = rotation;
6368 fschmid 1149
}
1150
 
1151
#ifdef HAVE_CAIRO
3113 fschmid 1152
void ScPainter::drawVPath( int mode )
68 Franz 1153
{
3113 fschmid 1154
        cairo_save( m_cr );
1155
        if (mode == 0)
1156
        {
1157
                if( m_fillRule )
1158
                        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_EVEN_ODD);
1159
                else
1160
                        cairo_set_fill_rule (m_cr, CAIRO_FILL_RULE_WINDING);
6368 fschmid 1161
                if (fillMode == 1)
3113 fschmid 1162
                {
6368 fschmid 1163
                        double r = qRed( m_fill.rgb() ) / 255.0;
1164
                        double g = qGreen( m_fill.rgb() ) / 255.0;
1165
                        double b = qBlue( m_fill.rgb() ) / 255.0;
1166
                        cairo_set_source_rgba( m_cr, r, g, b, fill_trans );
1167
                        cairo_fill_preserve( m_cr );
1168
                }
1169
                else if (fillMode == 2)
1170
                {
3113 fschmid 1171
                        cairo_pattern_t *pat;
7141 fschmid 1172
                        double x1 = fill_gradient.origin().x();
1173
                        double y1 = fill_gradient.origin().y();
1174
                        double x2 = fill_gradient.vector().x();
1175
                        double y2 = fill_gradient.vector().y();
3113 fschmid 1176
                        if (fill_gradient.type() == VGradient::linear)
1177
                                pat = cairo_pattern_create_linear (x1, y1,  x2, y2);
1178
                        else
1179
                                pat = cairo_pattern_create_radial (x1, y1, 0.1, x1, y1, sqrt(pow(x2 - x1, 2) + pow(y2 - y1,2)));
1180
                        QPtrVector<VColorStop> colorStops = fill_gradient.colorStops();
7175 fschmid 1181
                        QColor qStopColor;
3113 fschmid 1182
                        for( uint offset = 0 ; offset < colorStops.count() ; offset++ )
1183
                        {
7175 fschmid 1184
                                qStopColor = colorStops[ offset ]->color;
6795 jghali 1185
                                int h, s, v, sneu, vneu;
3113 fschmid 1186
                                int shad = colorStops[offset]->shade;
6795 jghali 1187
                                qStopColor.hsv(&h, &s, &v);
1188
                                sneu = s * shad / 100;
1189
                                vneu = 255 - ((255 - v) * shad / 100);
1190
                                qStopColor.setHsv(h, sneu, vneu);
3113 fschmid 1191
                                double r = qRed( qStopColor.rgb() ) / 255.0;
1192
                                double g = qGreen( qStopColor.rgb() ) / 255.0;
1193
                                double b = qBlue( qStopColor.rgb() ) / 255.0;
1194
                                double a = colorStops[offset]->opacity;
6368 fschmid 1195
                                cairo_pattern_add_color_stop_rgba (pat, colorStops[ offset ]->rampPoint, r, g, b, a);
3113 fschmid 1196
                        }
1197
                        cairo_set_source (m_cr, pat);
1198
                        cairo_clip_preserve (m_cr);
6368 fschmid 1199
                        cairo_paint_with_alpha (m_cr, fill_trans);
3113 fschmid 1200
                        cairo_pattern_destroy (pat);
1201
                }
6368 fschmid 1202
                else if (fillMode == 3)
3113 fschmid 1203
                {
6620 fschmid 1204
                        cairo_surface_t *image2 = cairo_image_surface_create_for_data ((uchar*)m_pattern->getPattern()->bits(), CAIRO_FORMAT_RGB24, m_pattern->getPattern()->width(), m_pattern->getPattern()->height(), m_pattern->getPattern()->width()*4);
6369 fschmid 1205
                        cairo_pattern_t *m_pat = cairo_pattern_create_for_surface(image2);
1206
                        cairo_pattern_set_extend(m_pat, CAIRO_EXTEND_REPEAT);
6608 fschmid 1207
                        QImage mask;
1208
                        cairo_surface_t *image3;
1209
                        if (fill_trans != 1.0)
1210
                        {
1211
                                mask.create(m_pattern->getPattern()->width(), m_pattern->getPattern()->height(), 8);
7175 fschmid 1212
                                QRgb * s;
1213
                                unsigned char *d;
6608 fschmid 1214
                                for( int yi = 0; yi < m_pattern->getPattern()->height(); ++yi )
1215
                                {
7175 fschmid 1216
                                        s = (QRgb*)(m_pattern->getPattern()->scanLine( yi ));
1217
                                        d = (unsigned char *)(mask.scanLine( yi ));
6608 fschmid 1218
                                        for( int xi=0; xi < m_pattern->getPattern()->width(); ++xi )
1219
                                        {
1220
                                                *d++ = static_cast<unsigned char>(qAlpha(*s++) * fill_trans);
1221
                                        }
1222
                                }
1223
                                int adj;
1224
                                if (m_pattern->getPattern()->width() % 4 == 0)
1225
                                        adj = 0;
1226
                                else
1227
                                        adj = 4 - (m_pattern->getPattern()->width() % 4);
1228
                                image3 = cairo_image_surface_create_for_data ((uchar*)mask.bits(), CAIRO_FORMAT_A8, m_pattern->getPattern()->width(), m_pattern->getPattern()->height(), m_pattern->getPattern()->width() + adj);
1229
                        }
1230
                        else
1231
                                image3 = 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);
6368 fschmid 1232
                        cairo_matrix_t matrix;
6414 fschmid 1233
                        QWMatrix qmatrix;
7141 fschmid 1234
//                      qmatrix.scale(m_zoomFactor, m_zoomFactor);
6414 fschmid 1235
                        qmatrix.translate(patternOffsetX, patternOffsetY);
1236
                        qmatrix.rotate(patternRotation);
1237
                        qmatrix.scale(patternScaleX, patternScaleY);
1238
                        cairo_matrix_init(&matrix, qmatrix.m11(), qmatrix.m12(), qmatrix.m21(), qmatrix.m22(), qmatrix.dx(), qmatrix.dy());
1239
                        cairo_matrix_invert(&matrix);
6368 fschmid 1240
                        cairo_pattern_set_matrix (m_pat, &matrix);
1241
                        cairo_set_source (m_cr, m_pat);
1242
                        cairo_clip_preserve (m_cr);
6608 fschmid 1243
                        cairo_pattern_t *m_pat2 = cairo_pattern_create_for_surface(image3);
1244
                        cairo_pattern_set_extend(m_pat2, CAIRO_EXTEND_REPEAT);
1245
                        cairo_pattern_set_matrix (m_pat2, &matrix);
1246
                        cairo_mask (m_cr, m_pat2);
6368 fschmid 1247
                        cairo_pattern_destroy (m_pat);
6608 fschmid 1248
                        cairo_pattern_destroy (m_pat2);
1249
                        cairo_surface_destroy (image2);
1250
                        cairo_surface_destroy (image3);
3113 fschmid 1251
                }
1252
        }
1253
        else
1254
        {
1255
                double *dashes;
7141 fschmid 1256
                cairo_set_line_width( m_cr, LineWidth );
3113 fschmid 1257
                if( m_array.count() > 0 )
1258
                {
1259
                        dashes = new double[ m_array.count() ];
1260
                        for( uint i = 0; i < m_array.count();++ i )
1261
                        {
7141 fschmid 1262
                                dashes[i] = static_cast<double>(m_array[i]);
3113 fschmid 1263
                        }
7141 fschmid 1264
                        cairo_set_dash( m_cr, dashes, m_array.count(), static_cast<double>(m_offset));
3113 fschmid 1265
                }
1266
                else
1267
                        cairo_set_dash( m_cr, NULL, 0, 0 );
1268
                double r = qRed( m_stroke.rgb() ) / 255.0;
1269
                double g = qGreen( m_stroke.rgb() ) / 255.0;
1270
                double b = qBlue( m_stroke.rgb() ) / 255.0;
6368 fschmid 1271
                cairo_set_source_rgba( m_cr, r, g, b, stroke_trans );
3113 fschmid 1272
                if( PLineEnd == Qt::RoundCap )
1273
                        cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_ROUND);
1274
                else if( PLineEnd == Qt::SquareCap )
1275
                        cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_SQUARE);
1276
                else if( PLineEnd == Qt::FlatCap )
1277
                        cairo_set_line_cap (m_cr, CAIRO_LINE_CAP_BUTT);
1278
                if( PLineJoin == Qt::RoundJoin )
1279
                        cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_ROUND );
1280
                else if( PLineJoin == Qt::BevelJoin )
1281
                        cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_BEVEL );
1282
                else if( PLineJoin == Qt::MiterJoin )
1283
                        cairo_set_line_join( m_cr, CAIRO_LINE_JOIN_MITER );
1284
                cairo_stroke_preserve( m_cr );
1285
                if( m_array.count() > 0 )
1286
                        delete [] dashes;
1287
        }
1288
        cairo_restore( m_cr );
1289
#else
5699 avox 1290
        // not HAVE_CAIRO
4646 subik 1291
void ScPainter::drawVPath( struct _ArtVpath *vec, int mode, bool preCal )
68 Franz 1292
{
1293
        ArtSVP *strokeSvp = 0L;
1294
        ArtSVP *fillSvp = 0L;
1998 fschmid 1295
        if (!preCal)
1296
        {
1297
                double affine[6];
1298
                affine[0] = m_matrix.m11();
1299
                affine[1] = m_matrix.m12();
1300
                affine[2] = m_matrix.m21();
1301
                affine[3] = m_matrix.m22();
1302
                affine[4] = m_matrix.dx();
1303
                affine[5] = m_matrix.dy();
1304
                ArtVpath *temp1 = art_vpath_affine_transform( vec, affine );
1305
                art_free( vec );
1306
                vec = temp1;
1307
        }
68 Franz 1308
        int af = 0;
1309
        int as = 0;
1310
        art_u32 fillColor = 0;
1311
        QColor color;
1312
        if (mode == 0)
1313
                {
1314
                color = m_fill;
1315
                af = qRound( 255 * fill_trans );
86 Franz 1316
#ifdef WORDS_BIGENDIAN
1317
                fillColor = ( color.red() << 24 ) | ( color.green() << 16 ) | ( color.blue() << 8 );
1318
#else
1319
                fillColor = ( 0 << 24 ) | ( color.blue() << 16 ) | ( color.green() << 8 ) | color.red();
1320
#endif
68 Franz 1321
                ArtSvpWriter *swr;
1322
                ArtSVP *temp;
6461 fschmid 1323
                ArtSVP *temp2;
68 Franz 1324
                temp = art_svp_from_vpath( vec );
1325
                if( m_fillRule )
1326
                        swr = art_svp_writer_rewind_new( ART_WIND_RULE_ODDEVEN );
1327
                else
1328
                        swr = art_svp_writer_rewind_new( ART_WIND_RULE_NONZERO );
1329
                art_svp_intersector( temp, swr );
1330
                fillSvp = art_svp_writer_rewind_reap( swr );
1331
                art_svp_free( temp );
1332
                }
1333
        art_u32 strokeColor = 0;
1334
        if (mode == 1)
1335
                {
1336
                ArtPathStrokeCapType capStyle = ART_PATH_STROKE_CAP_BUTT;
1337
                ArtPathStrokeJoinType joinStyle = ART_PATH_STROKE_JOIN_MITER;
1338
                color = m_stroke;
1339
                as = qRound( 255 * stroke_trans );
86 Franz 1340
#ifdef WORDS_BIGENDIAN
5699 avox 1341
                strokeColor = ( color.red() << 24 ) | ( color.green() << 16 ) | ( color.blue() << 8 );
86 Franz 1342
#else
68 Franz 1343
                strokeColor = ( 0 << 24 ) | ( color.blue() << 16 ) | ( color.green() << 8 ) | color.red();
86 Franz 1344
#endif
3113 fschmid 1345
                double ratio = m_zoomFactor;
68 Franz 1346
                if( m_array.count() > 0 )
1347
                        {
1348
                        ArtVpathDash dash;
1349
                        dash.offset = static_cast<double>(m_offset) * ratio;
1350
                        dash.n_dash = m_array.count();
1351
                        double *dashes = new double[ dash.n_dash ];
1352
                        for( int i = 0; i < dash.n_dash; i++ )
1353
                                {
1354
                                dashes[i] = static_cast<double>(m_array[i]) * ratio;
1355
                                }
1356
                        dash.dash = dashes;
1357
                        ArtVpath *vec2 = art_vpath_dash( vec, &dash );
1358
                        art_free( vec );
1359
                        vec = vec2;
1360
                        delete [] dashes;
1361
                        }
1362
                if( PLineEnd == Qt::RoundCap )
1363
                        capStyle = ART_PATH_STROKE_CAP_ROUND;
1364
                else if( PLineEnd == Qt::SquareCap )
1365
                        capStyle = ART_PATH_STROKE_CAP_SQUARE;
1366
                if( PLineJoin == Qt::RoundJoin )
1367
                        joinStyle = ART_PATH_STROKE_JOIN_ROUND;
1368
                else if( PLineJoin == Qt::BevelJoin )
1369
                        joinStyle = ART_PATH_STROKE_JOIN_BEVEL;
5096 mrdocs 1370
                //strokeSvp = art_svp_vpath_stroke( vec, joinStyle, capStyle, ratio * LineWidth, 10, 0.25 );
1371
                ArtVpath* strokeVpath = art_svp_vpath_stroke_raw( vec, joinStyle, capStyle, ratio * LineWidth, 10, 0.25 );
1372
                strokeSvp = art_svp_from_vpath( strokeVpath );
1373
                art_free(strokeVpath);
68 Franz 1374
                }
1375
        int x0, y0, x1, y1;
237 Franz 1376
        if(( fillSvp ) && (mode == 0))
68 Franz 1377
                {
1378
                if (fillMode == 2)
1379
                        applyGradient( fillSvp, true );
6368 fschmid 1380
                else if (fillMode == 3)
1381
                        applyPattern(fillSvp);
68 Franz 1382
                else
6368 fschmid 1383
                {
68 Franz 1384
                        clampToViewport( *fillSvp, x0, y0, x1, y1 );
1385
                        if( x0 != x1 && y0 != y1 )
1386
                                art_rgb_svp_alpha_( fillSvp, x0, y0, x1, y1, fillColor, af, m_buffer + x0 * 4 + y0 * m_width * 4, m_width * 4, 0 );
6368 fschmid 1387
                }
68 Franz 1388
                art_svp_free( fillSvp );
1389
                }
237 Franz 1390
        if(( strokeSvp ) && (mode == 1))
68 Franz 1391
        {
1392
                        clampToViewport( *strokeSvp, x0, y0, x1, y1 );
1393
                        if( x0 != x1 && y0 != y1 )
1394
                                art_rgb_svp_alpha_( strokeSvp, x0, y0, x1, y1, strokeColor, as, m_buffer + x0 * 4 + y0 * m_width * 4, m_width * 4, 0 );
1395
                art_svp_free( strokeSvp );
1396
        }
1397
        art_free( vec );
3113 fschmid 1398
#endif
68 Franz 1399
}
1400
 
267 Franz 1401
void ScPainter::setClipPath()
1402
{
3113 fschmid 1403
#ifdef HAVE_CAIRO
1404
        cairo_clip (m_cr);
1405
#else
267 Franz 1406
        ArtVpath *vec = art_bez_path_to_vec( m_path , 0.25 );
1407
        double affine[6];
1408
        affine[0] = m_matrix.m11();
632 fschmid 1409
        affine[1] = m_matrix.m12();
1410
        affine[2] = m_matrix.m21();
267 Franz 1411
        affine[3] = m_matrix.m22();
1412
        affine[4] = m_matrix.dx();
1413
        affine[5] = m_matrix.dy();
1414
        ArtVpath *temp1 = art_vpath_affine_transform( vec, affine );
1415
        art_free( vec );
1416
        ArtSvpWriter *swr;
268 Franz 1417
        ArtSVP *temp = art_svp_from_vpath( temp1 );
267 Franz 1418
        if( m_fillRule )
1419
                swr = art_svp_writer_rewind_new( ART_WIND_RULE_ODDEVEN );
1420
        else
1421
                swr = art_svp_writer_rewind_new( ART_WIND_RULE_NONZERO );
1422
        art_svp_intersector( temp, swr );
1423
        m_clipPath = art_svp_writer_rewind_reap( swr );
1424
        art_svp_free( temp );
268 Franz 1425
        art_free( temp1 );
3113 fschmid 1426
#endif
267 Franz 1427
}
1428
 
5699 avox 1429
#ifdef HAVE_CAIRO
1430
#else
4748 fschmid 1431
void ScPainter::setClipPath2(FPointArray *points, bool closed)
1432
{
1433
        setClipPath();
1434
        setupPolygon(points, closed);
1435
        ArtVpath *vec = art_bez_path_to_vec( m_path , 0.25 );
1436
        double affine[6];
1437
        affine[0] = m_matrix.m11();
1438
        affine[1] = m_matrix.m12();
1439
        affine[2] = m_matrix.m21();
1440
        affine[3] = m_matrix.m22();
1441
        affine[4] = m_matrix.dx();
1442
        affine[5] = m_matrix.dy();
1443
        ArtVpath *temp1 = art_vpath_affine_transform( vec, affine );
1444
        art_free( vec );
1445
        ArtSvpWriter *swr;
1446
        ArtSVP *temp = art_svp_from_vpath( temp1 );
1447
        if( m_fillRule )
1448
                swr = art_svp_writer_rewind_new( ART_WIND_RULE_ODDEVEN );
1449
        else
1450
                swr = art_svp_writer_rewind_new( ART_WIND_RULE_NONZERO );
1451
        art_svp_intersector( temp, swr );
1452
        temp = art_svp_writer_rewind_reap( swr );
1453
        ArtSVP *temp2 = art_svp_intersect( temp, m_clipPath );
1454
        m_clipPath = temp2;
1455
        art_svp_free( temp );
1456
        art_free( temp1 );
1457
}
5699 avox 1458
// not HAVE_CAIRO
4748 fschmid 1459
#endif
1460
 
270 Franz 1461
void ScPainter::drawImage( QImage *image )
68 Franz 1462
{
3113 fschmid 1463
#ifdef HAVE_CAIRO
6856 fschmid 1464
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 2, 6)
1465
/* Code with Layers, crashes on cairo_push_group */
7141 fschmid 1466
//      cairo_scale(m_cr, m_zoomFactor, m_zoomFactor);
6312 fschmid 1467
        cairo_push_group(m_cr);
3113 fschmid 1468
        cairo_set_fill_rule(m_cr, cairo_get_fill_rule(m_cr));
6312 fschmid 1469
        cairo_surface_t *image2  = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_RGB24, image->width(), image->height(), image->width()*4);
1470
        cairo_surface_t *image3 = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_ARGB32, image->width(), image->height(), image->width()*4);
1471
        cairo_set_source_surface (m_cr, image2, 0, 0);
1472
    cairo_mask_surface (m_cr, image3, 0, 0);
1473
        cairo_surface_destroy (image2);
1474
        cairo_surface_destroy (image3);
1475
        cairo_pop_group_to_source (m_cr);
1476
        cairo_paint_with_alpha (m_cr, fill_trans);
6856 fschmid 1477
#else
6312 fschmid 1478
/* Working code, sadly we need to create an additional mask image with the same size as the image to be painted */
6314 fschmid 1479
        cairo_surface_t *image3;
1480
        QImage mask;
6312 fschmid 1481
        cairo_set_fill_rule(m_cr, cairo_get_fill_rule(m_cr));
1482
        cairo_surface_t *image2  = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_RGB24, image->width(), image->height(), image->width()*4);
6314 fschmid 1483
        if (fill_trans != 1.0)
6312 fschmid 1484
        {
6315 fschmid 1485
                mask.create(image->width(), image->height(), 8);
6314 fschmid 1486
                for( int yi = 0; yi < image->height(); ++yi )
6312 fschmid 1487
                {
6314 fschmid 1488
                        QRgb * s = (QRgb*)(image->scanLine( yi ));
6315 fschmid 1489
                        unsigned char *d = (unsigned char *)(mask.scanLine( yi ));
6314 fschmid 1490
                        for( int xi=0; xi < image->width(); ++xi )
1491
                        {
6315 fschmid 1492
                                *d++ = static_cast<unsigned char>(qAlpha(*s++) * fill_trans);
6314 fschmid 1493
                        }
6312 fschmid 1494
                }
6315 fschmid 1495
                int adj;
1496
                if (image->width() % 4 == 0)
1497
                        adj = 0;
1498
                else
1499
                        adj = 4 - (image->width() % 4);
1500
                image3 = cairo_image_surface_create_for_data ((uchar*)mask.bits(), CAIRO_FORMAT_A8, image->width(), image->height(), image->width() + adj);
6312 fschmid 1501
        }
6314 fschmid 1502
        else
1503
                image3 = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_ARGB32, image->width(), image->height(), image->width()*4);
7141 fschmid 1504
//      cairo_scale(m_cr, m_zoomFactor, m_zoomFactor);
3113 fschmid 1505
        cairo_set_source_surface (m_cr, image2, 0, 0);
6312 fschmid 1506
        cairo_mask_surface (m_cr, image3, 0, 0);
1507
        cairo_surface_destroy (image2);
1508
        cairo_surface_destroy (image3);
6856 fschmid 1509
#endif
6312 fschmid 1510
/* Original Code       
1511
        cairo_set_fill_rule(m_cr, cairo_get_fill_rule(m_cr));
1512
        cairo_surface_t *image2  = cairo_image_surface_create_for_data ((uchar*)image->bits(), CAIRO_FORMAT_ARGB32, image->width(), image->height(), image->width()*4);
1513
        cairo_scale(m_cr, m_zoomFactor, m_zoomFactor);
1514
        cairo_set_source_surface (m_cr, image2, 0, 0);
3113 fschmid 1515
        cairo_paint_with_alpha(m_cr, fill_trans);
1516
        cairo_surface_destroy (image2);
6312 fschmid 1517
*/
3113 fschmid 1518
#else
68 Franz 1519
        double affineresult[6];
1520
        affineresult[0] = m_matrix.m11() * m_zoomFactor;
1521
        affineresult[1] = m_matrix.m12() * m_zoomFactor;
1522
        affineresult[2] = m_matrix.m21() * m_zoomFactor;
1523
        affineresult[3] = m_matrix.m22() * m_zoomFactor;
632 fschmid 1524
        affineresult[4] = m_matrix.dx();
1525
        affineresult[5] = m_matrix.dy();
267 Franz 1526
        ksvg_art_rgb_affine_clip( m_clipPath, m_buffer, 0, 0, m_width, m_height, m_width * 4, 4,
270 Franz 1527
                                         image->bits(), image->width(), image->height(), image->width() * 4,
267 Franz 1528
                                         affineresult, qRound( 255 * fill_trans ), 0L );
1529
        art_svp_free( m_clipPath );
6461 fschmid 1530
        m_clipPath = 0;
3113 fschmid 1531
#endif
68 Franz 1532
}
1533
 
264 Franz 1534
void ScPainter::setupPolygon(FPointArray *points, bool closed)
68 Franz 1535
{
1536
        bool nPath = true;
1537
        FPoint np, np1, np2, np3;
3113 fschmid 1538
#ifdef HAVE_CAIRO
68 Franz 1539
        if (points->size() > 3)
3113 fschmid 1540
        {
1541
                newPath();
1542
                for (uint poi=0; poi<points->size()-3; poi += 4)
68 Franz 1543
                {
3113 fschmid 1544
                        if (points->point(poi).x() > 900000)
1545
                        {
1546
                                nPath = true;
1547
                                continue;
1548
                        }
1549
                        if (nPath)
1550
                        {
1551
                                np = points->point(poi);
7141 fschmid 1552
                        cairo_move_to( m_cr, np.x(), np.y());
3113 fschmid 1553
                                nPath = false;
1554
                        }
1555
                        np = points->point(poi);
1556
                        np1 = points->point(poi+1);
1557
                        np2 = points->point(poi+3);
1558
                        np3 = points->point(poi+2);
1559
                        if ((np == np1) && (np2 == np3))
7141 fschmid 1560
                                cairo_line_to( m_cr, np3.x(), np3.y());
3113 fschmid 1561
                        else
7141 fschmid 1562
                                cairo_curve_to(m_cr, np1.x(), np1.y(), np2.x(), np2.y(), np3.x(), np3.y());
3113 fschmid 1563
                }
1564
                if (closed)
1565
                cairo_close_path( m_cr );
1566
        }
1567
#else
5699 avox 1568
        // not HAVE_CAIRO
3113 fschmid 1569
        if (points->size() > 3)
1570
                {
68 Franz 1571
                newPath();
1572
                for (uint poi=0; poi<points->size()-3; poi += 4)
1573
                        {
1574
                        if (points->point(poi).x() > 900000)
1575
                                {
1576
                                nPath = true;
173 Franz 1577
                                ensureSpace( m_index + 1 );
1578
                                m_path[ m_index ].code = ART_END;
68 Franz 1579
                                continue;
1580
                                }
1581
                        if (nPath)
1582
                                {
1583
                                np = points->point(poi);
1584
                                ensureSpace( m_index + 1 );
264 Franz 1585
                                if (closed)
1586
                                        m_path[ m_index ].code = ART_MOVETO;
1587
                                else
1588
                                        m_path[ m_index ].code = ART_MOVETO_OPEN;
86 Franz 1589
                                m_path[ m_index ].x3 = np.x() * m_zoomFactor;
1590
                                m_path[ m_index ].y3 = np.y() * m_zoomFactor;
68 Franz 1591
                                m_index++;
1592
                                nPath = false;
1593
                                }
1594
                        np = points->point(poi);
1595
                        np1 = points->point(poi+1);
1596
                        np2 = points->point(poi+3);
1597
                        np3 = points->point(poi+2);
1598
                        ensureSpace( m_index + 1 );
1599
                        if ((np == np1) && (np2 == np3))
1600
                                {
1601
                                m_path[ m_index ].code = ART_LINETO;
86 Franz 1602
                                m_path[ m_index ].x3    = np3.x() * m_zoomFactor;
1603
                                m_path[ m_index ].y3    = np3.y() * m_zoomFactor;
68 Franz 1604
                                }
1605
                        else
1606
                                {
1607
                                m_path[ m_index ].code = ART_CURVETO;
86 Franz 1608
                                m_path[ m_index ].x1    = np1.x() * m_zoomFactor;
1609
                                m_path[ m_index ].y1    = np1.y() * m_zoomFactor;
1610
                                m_path[ m_index ].x2    = np2.x() * m_zoomFactor;
1611
                                m_path[ m_index ].y2    = np2.y() * m_zoomFactor;
1612
                                m_path[ m_index ].x3    = np3.x() * m_zoomFactor;
1613
                                m_path[ m_index ].y3    = np3.y() * m_zoomFactor;
68 Franz 1614
                                }
1615
                        m_index++;
1616
                        }
173 Franz 1617
                ensureSpace( m_index + 1 );
1618
                m_path[ m_index ].code = ART_END;
1619
                m_index++;
68 Franz 1620
                }
3113 fschmid 1621
#endif
68 Franz 1622
}
1623
 
638 fschmid 1624
void ScPainter::setupTextPolygon(FPointArray *points)
1625
{
1626
        bool nPath = true;
1627
        FPoint np, np1, np2, np3;
3113 fschmid 1628
#ifdef HAVE_CAIRO
1629
        if (points->size() > 3)
1630
        {
1631
                newPath();
1632
                for (uint poi=0; poi<points->size()-3; poi += 4)
1633
                {
1634
                        if (points->point(poi).x() > 900000)
1635
                        {
1636
                                nPath = true;
1637
                                continue;
1638
                        }
1639
                        if (nPath)
1640
                        {
1641
                                np = points->point(poi);
1642
                        cairo_move_to( m_cr, np.x(), np.y());
1643
                                nPath = false;
1644
                        }
1645
                        np = points->point(poi);
1646
                        np1 = points->point(poi+1);
1647
                        np2 = points->point(poi+3);
1648
                        np3 = points->point(poi+2);
1649
                        if ((np == np1) && (np2 == np3))
1650
                                cairo_line_to( m_cr, np3.x(), np3.y());
1651
                        else
1652
                                cairo_curve_to(m_cr, np1.x(), np1.y(), np2.x(), np2.y(), np3.x(), np3.y());
1653
                }
1654
        cairo_close_path( m_cr );
1655
        }
1656
#else
638 fschmid 1657
        newPath();
1658
        for (uint poi=0; poi<points->size()-3; poi += 4)
1659
        {
1660
                if (points->point(poi).x() > 900000)
1661
                {
1662
                        nPath = true;
1663
                        ensureSpace( m_index + 1 );
1664
                        m_path[ m_index ].code = ART_END;
1665
                        continue;
1666
                }
1667
                if (nPath)
1668
                {
1669
                        np = points->point(poi);
1670
                        ensureSpace( m_index + 1 );
1671
                        m_path[ m_index ].code = ART_MOVETO;
1672
                        m_path[ m_index ].x3 = np.x();
1673
                        m_path[ m_index ].y3 = np.y();
1674
                        m_index++;
1675
                        nPath = false;
1676
                }
1677
                np = points->point(poi);
1678
                np1 = points->point(poi+1);
1679
                np2 = points->point(poi+3);
1680
                np3 = points->point(poi+2);
1681
                ensureSpace( m_index + 1 );
1682
                if ((np == np1) && (np2 == np3))
1683
                {
1684
                        m_path[ m_index ].code = ART_LINETO;
1685
                        m_path[ m_index ].x3    = np3.x();
1686
                        m_path[ m_index ].y3    = np3.y();
1687
                }
1688
                else
1689
                {
1690
                        m_path[ m_index ].code = ART_CURVETO;
1691
                        m_path[ m_index ].x1    = np1.x();
1692
                        m_path[ m_index ].y1    = np1.y();
1693
                        m_path[ m_index ].x2    = np2.x();
1694
                        m_path[ m_index ].y2    = np2.y();
1695
                        m_path[ m_index ].x3    = np3.x();
1696
                        m_path[ m_index ].y3    = np3.y();
1697
                }
1698
                m_index++;
1699
        }
1700
        ensureSpace( m_index + 1 );
1701
        m_path[ m_index ].code = ART_END;
1702
        m_index++;
3113 fschmid 1703
#endif
638 fschmid 1704
}
1705
 
68 Franz 1706
void ScPainter::drawPolygon()
1707
{
1708
        fillPath();
1709
}
1710
 
1711
void ScPainter::drawPolyLine()
1712
{
1713
        strokePath();
1714
}
1715
 
1716
void ScPainter::drawLine(FPoint start, FPoint end)
1717
{
1718
        newPath();
1719
        moveTo(start.x(), start.y());
1720
        lineTo(end.x(), end.y());
1721
        strokePath();
1722
}
1723
 
1724
void ScPainter::drawRect(double x, double y, double w, double h)
1725
{
1726
        newPath();
1727
        moveTo( x, y );
1728
        lineTo( x+w, y );
1729
        lineTo( x+w, y+h );
1730
        lineTo( x, y+h );
1731
        lineTo( x, y );
3113 fschmid 1732
#ifdef HAVE_CAIRO
1733
        cairo_close_path( m_cr );
1734
#else
173 Franz 1735
        ensureSpace( m_index + 1 );
1736
        m_path[ m_index ].code = ART_END;
1737
        m_index++;
3113 fschmid 1738
#endif
68 Franz 1739
        fillPath();
1740
        strokePath();
1741
}
3113 fschmid 1742
 
5699 avox 1743
#ifdef HAVE_CAIRO
1744
#else
3113 fschmid 1745
void ScPainter::ensureSpace( unsigned int newindex )
1746
{
1747
        if( m_index == 0 )
1748
                {
1749
                if( !m_path )
1750
                        m_path = art_new( ArtBpath, INITIAL_ALLOC );
1751
                m_alloccount = INITIAL_ALLOC;
1752
                }
1753
        else if( newindex > m_alloccount )
1754
                {
1755
                m_alloccount += ALLOC_INCREMENT;
1756
                m_path = art_renew( m_path, ArtBpath, m_alloccount );
1757
                }
1758
}
1759
 
1760
void ScPainter::resize( unsigned int w, unsigned int h )
1761
{
1762
        if( !m_buffer || w != m_width || h != m_height )
1763
        {
1764
                // TODO : realloc?
1765
                art_free( m_buffer );
1766
                m_buffer = 0;
1767
                m_width = w;
1768
                m_height = h;
1769
                if ( m_width != 0 && m_height != 0 )
1770
                        m_buffer = art_new( art_u8, m_width * m_height * 4 );
1771
                clear();
1772
        }
1773
}
1774
 
1775
void ScPainter::clampToViewport( int &x0, int &y0, int &x1, int &y1 )
1776
{
1777
        x0 = QMAX( x0, 0 );
1778
        x0 = QMIN( x0, static_cast<int>( m_width ) );
1779
        y0 = QMAX( y0, 0 );
1780
        y0 = QMIN( y0, static_cast<int>( m_height ) );
1781
        x1 = QMAX( x1, 0 );
1782
        x1 = QMIN( x1, static_cast<int>( m_width ) );
1783
        y1 = QMAX( y1, 0 );
1784
        y1 = QMIN( y1, static_cast<int>( m_height ) );
1785
}
1786
 
4646 subik 1787
void ScPainter::clampToViewport( const _ArtSVP &svp, int &x0, int &y0, int &x1, int &y1 )
3113 fschmid 1788
{
1789
        ArtDRect bbox;
1790
        art_drect_svp( &bbox, &svp );
1791
        x0 = static_cast<int>( bbox.x0 );
1792
        x0 = QMAX( x0, 0 );
1793
        x0 = QMIN( x0, static_cast<int>( m_width ) );
1794
        y0 = static_cast<int>( bbox.y0 );
1795
        y0 = QMAX( y0, 0 );
1796
        y0 = QMIN( y0, static_cast<int>( m_height ) );
1797
        x1 = static_cast<int>( bbox.x1 ) + 1;
1798
        x1 = QMAX( x1, 0 );
1799
        x1 = QMIN( x1, static_cast<int>( m_width ) );
1800
        y1 = static_cast<int>( bbox.y1 ) + 1;
1801
        y1 = QMAX( y1, 0 );
1802
        y1 = QMIN( y1, static_cast<int>( m_height ) );
1803
}
1804
 
4646 subik 1805
void ScPainter::applyGradient( _ArtSVP *svp, bool fill )
3113 fschmid 1806
{
1807
        int x0, y0, x1, y1;
1808
        clampToViewport( *svp, x0, y0, x1, y1 );
1809
        ArtRender *render = 0L;
1810
        VGradient gradient;
1811
        if (fill)
1812
                gradient = fill_gradient;
1813
        else
1814
                gradient = stroke_gradient;
1815
        double opa = fill ? fill_trans : stroke_trans;
1816
        if (gradient.type() == VGradient::linear)
1817
        {
1818
                ArtGradientLinear *linear = art_new( ArtGradientLinear, 1 );
1819
                linear->spread = ART_GRADIENT_PAD;
1820
                double _x1 = static_cast<double>(gradient.origin().x());
1821
                double _x2 = static_cast<double>(gradient.vector().x());
1822
                double _y2 = static_cast<double>(gradient.origin().y());
1823
                double _y1 = static_cast<double>(gradient.vector().y());
1824
                double dx = ( _x2 - _x1 ) * m_zoomFactor;
1825
                _y1 =  _y1 + m_matrix.dy() / m_zoomFactor;
1826
                _y2 =  _y2 + m_matrix.dy() / m_zoomFactor;
1827
                if (dx == 0.0)
1828
                        dx = 1;
1829
                double dy = ( _y1 - _y2 ) * m_zoomFactor;
1830
                if (dy == 0.0)
1831
                        dy = 1;
1832
                double scale = 1.0 / ( dx * dx + dy * dy );
1833
                linear->a = dx * scale;
1834
                linear->b = dy * scale;
1835
                linear->c = -( ( _x1 * m_zoomFactor + m_matrix.dx() ) * linear->a + ( _y2 * m_zoomFactor ) * linear->b );
1836
                int offsets = -1;
1837
                linear->stops = buildStopArray( gradient, offsets );
1838
                linear->n_stops = offsets;
1839
                if( x0 != x1 && y0 != y1 )
1840
                {
1841
                        render = art_render_new( x0, y0, x1, y1, m_buffer + 4 * static_cast<int>(x0) + m_width * 4 * static_cast<int>(y0), m_width * 4, 3, 8, ART_ALPHA_PREMUL, 0 );
1842
                        int opacity = static_cast<int>( opa * 255.0 );
1843
                        art_render_svp( render, svp );
1844
                        art_render_mask_solid (render, (opacity << 8) + opacity + (opacity >> 7));
1845
                        art_karbon_render_gradient_linear( render, linear, ART_FILTER_NEAREST );
1846
                        art_render_invoke( render );
1847
                }
1848
                art_free( linear->stops );
1849
                art_free( linear );
1850
        }
1851
        else if( gradient.type() == VGradient::radial )
1852
        {
1853
                ArtGradientRadial *radial = art_new( ArtGradientRadial, 1 );
1854
                radial->spread = ART_GRADIENT_PAD;
1855
                radial->affine[0] = m_matrix.m11();
1856
                radial->affine[1] = m_matrix.m12();
1857
                radial->affine[2] = m_matrix.m21();
1858
                radial->affine[3] = m_matrix.m22();
1859
                radial->affine[4] = m_matrix.dx();
1860
                radial->affine[5] = m_matrix.dy();
1861
                double cx = gradient.origin().x() * m_zoomFactor;
1862
                double cy = gradient.origin().y() * m_zoomFactor;
1863
                double fx = gradient.focalPoint().x() * m_zoomFactor;
1864
                double fy = gradient.focalPoint().y() * m_zoomFactor;
1865
                double r = sqrt( pow( gradient.vector().x() - gradient.origin().x(), 2 ) + pow( gradient.vector().y() - gradient.origin().y(), 2 ) );
1866
                r *= m_zoomFactor;
1867
                radial->fx = (fx - cx) / r;
1868
                radial->fy = (fy - cy) / r;
1869
                double aff1[6], aff2[6];
1870
                art_affine_scale( aff1, r, r);
1871
                art_affine_translate( aff2, cx, cy );
1872
                art_affine_multiply( aff1, aff1, aff2 );
1873
                art_affine_multiply( aff1, aff1, radial->affine );
1874
                art_affine_invert( radial->affine, aff1 );
1875
                int offsets = -1;
1876
                radial->stops = buildStopArray( gradient, offsets );
1877
                radial->n_stops = offsets;
1878
                if( x0 != x1 && y0 != y1 )
1879
                {
1880
                        render = art_render_new( x0, y0, x1, y1, m_buffer + 4 * x0 + m_width * 4 * y0, m_width * 4, 3, 8, ART_ALPHA_PREMUL, 0 );
1881
                        int opacity = static_cast<int>( opa * 255.0 );
1882
                        art_render_svp( render, svp );
1883
                        art_render_mask_solid (render, (opacity << 8) + opacity + (opacity >> 7));
1884
                        art_karbon_render_gradient_radial( render, radial, ART_FILTER_NEAREST );
1885
                        art_render_invoke( render );
1886
                }
1887
                art_free( radial->stops );
1888
                art_free( radial );
1889
        }
1890
}
1891
 
1892
ArtGradientStop * ScPainter::buildStopArray( VGradient &gradient, int &offsets )
1893
{
1894
        QPtrVector<VColorStop> colorStops = gradient.colorStops();
1895
        offsets = colorStops.count();
1896
        ArtGradientStop *stopArray = art_new( ArtGradientStop, offsets * 2 - 1 );
1897
        for( int offset = 0 ; offset < offsets ; offset++ )
1898
        {
1899
                double ramp = colorStops[ offset ]->rampPoint;
1900
                stopArray[ offset * 2 ].offset = ramp;
1901
                QColor qStopColor = colorStops[ offset ]->color;
6795 jghali 1902
                int h, s, v, sneu, vneu;
3113 fschmid 1903
                int shad = colorStops[offset]->shade;
6795 jghali 1904
                qStopColor.hsv(&h, &s, &v);
1905
                sneu = s * shad / 100;
1906
                vneu = 255 - ((255 - v) * shad / 100);
1907
                qStopColor.setHsv(h, sneu, vneu);
3113 fschmid 1908
                int r = qRed( qStopColor.rgb() );
1909
                int g = qGreen( qStopColor.rgb() );
1910
                int b = qBlue( qStopColor.rgb() );
1911
                art_u32 rgba = (r << 24) | (g << 16) | (b << 8) | qAlpha(qStopColor.rgb());
1912
                int a = static_cast<int>( colorStops[offset]->opacity * 255.0 );
1913
                r = (rgba >> 24) * a + 0x80;
1914
                r = (r + (r >> 8)) >> 8;
1915
                g = ((rgba >> 16) & 0xff) * a + 0x80;
1916
                g = (g + (g >> 8)) >> 8;
1917
                b = ((rgba >> 8) & 0xff) * a + 0x80;
1918
                b = (b + (b >> 8)) >> 8;
1919
                stopArray[ offset * 2 ].color[ 0 ] = ART_PIX_MAX_FROM_8(r);
1920
                stopArray[ offset * 2 ].color[ 1 ] = ART_PIX_MAX_FROM_8(g);
1921
                stopArray[ offset * 2 ].color[ 2 ] = ART_PIX_MAX_FROM_8(b);
1922
                stopArray[ offset * 2 ].color[ 3 ] = ART_PIX_MAX_FROM_8(a);
1923
                if( offset + 1 != offsets )
1924
                {
1925
                        stopArray[ offset * 2 + 1 ].offset = ramp + ( colorStops[ offset + 1 ]->rampPoint - ramp ) * colorStops[ offset ]->midPoint;
1926
                        QColor qStopColor2 = colorStops[ offset + 1 ]->color;
1927
                        rgba = static_cast<int>(r + ((qRed(qStopColor2.rgb()) - r)) * 0.5) << 24 |
1928
                                                 static_cast<int>(g + ((qGreen(qStopColor2.rgb()) - g)) * 0.5) << 16 |
1929
                                                 static_cast<int>(b + ((qBlue(qStopColor2.rgb()) - b)) * 0.5) << 8 |
1930
                                                qAlpha(qStopColor2.rgb());
1931
                        int a = static_cast<int>( colorStops[offset]->opacity * 255.0 );
1932
                        r = (rgba >> 24) * a + 0x80;
1933
                        r = (r + (r >> 8)) >> 8;
1934
                        g = ((rgba >> 16) & 0xff) * a + 0x80;
1935
                        g = (g + (g >> 8)) >> 8;
1936
                        b = ((rgba >> 8) & 0xff) * a + 0x80;
1937
                        b = (b + (b >> 8)) >> 8;
1938
                        stopArray[ offset * 2 + 1 ].color[ 0 ] = ART_PIX_MAX_FROM_8(r);
1939
                        stopArray[ offset * 2 + 1 ].color[ 1 ] = ART_PIX_MAX_FROM_8(g);
1940
                        stopArray[ offset * 2 + 1 ].color[ 2 ] = ART_PIX_MAX_FROM_8(b);
1941
                        stopArray[ offset * 2 + 1 ].color[ 3 ] = ART_PIX_MAX_FROM_8(a);
1942
                }
1943
        }
1944
        offsets = offsets * 2 - 1;
1945
        return stopArray;
1946
}
6368 fschmid 1947
 
1948
void ScPainter::applyPattern( ArtSVP *svp)
1949
{
1950
        if(!svp)
1951
                return;
1952
        int x0, y0, x1, y1;
1953
        clampToViewport( *svp, x0, y0, x1, y1 );
1954
        ArtRender *render = 0L;
1955
        ArtPattern *pattern = art_new( ArtPattern, 1 );
1956
        double dx = 0.0;
1957
        double dy =0.0;
6516 fschmid 1958
        QImage pat = m_pattern->getPattern()->scale(m_pattern->getPattern()->width() * m_zoomFactor * patternScaleX, m_pattern->getPattern()->height() * m_zoomFactor * patternScaleY);
6368 fschmid 1959
        pattern->twidth = pat.width();
1960
        pattern->theight = pat.height();
1961
        pattern->buffer = pat.bits();
1962
        pattern->opacity = qRound( 255 * fill_trans );
6516 fschmid 1963
        pattern->angle = patternRotation * 3.1415927 / 180.0;
6368 fschmid 1964
        if( x0 != x1 && y0 != y1 )
1965
        {
1966
                render = art_render_new( x0, y0, x1, y1, m_buffer + 4 * int(x0) + m_width * 4 * int(y0), m_width * 4, 3, 8, ART_ALPHA_PREMUL, 0 );
1967
                art_render_svp( render, svp );
1968
                art_render_pattern( render, pattern, ART_FILTER_HYPER );
1969
        }
1970
        if( render )
1971
                art_render_invoke( render );
1972
        art_free( pattern );
1973
}
5699 avox 1974
//not HAVE_CAIRO
3113 fschmid 1975
#endif