Subversion Repositories Scribus

Rev

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