Subversion Repositories Scribus

Rev

Rev 8562 | 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
*/
4360 cbradney 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
#ifdef WIN32_LEAN_AND_MEAN
29
#undef WIN32_LEAN_AND_MEAN
30
#endif
31
 
32
#include <valarray>
33
#include <windows.h>
34
 
5659 jghali 35
#include "scconfig.h"
36
 
37
#ifdef SC_USE_GDIPLUS
4360 cbradney 38
#include <gdiplus.h>
8501 cbradney 39
//Added by qt3to4:
40
#include <Q3ValueList>
4360 cbradney 41
using namespace Gdiplus;
5659 jghali 42
#endif
4360 cbradney 43
 
7478 jghali 44
#include "scribusdoc.h"
4360 cbradney 45
#include "scpainterex_gdi.h"
7478 jghali 46
#include "sccolorengine.h"
4360 cbradney 47
 
48
#include <qpaintdevice.h>
49
#include <qpixmap.h>
8501 cbradney 50
#include <q3pointarray.h>
4360 cbradney 51
#include <qimage.h>
52
 
53
#include <iostream>
54
using namespace std;
55
 
56
#include <math.h>
57
 
58
typedef struct {
59
    BITMAPINFOHEADER bmiHeader;
60
    RGBQUAD bmiColors[256];
61
} BITMAPINFO256;
62
 
7478 jghali 63
ScPainterEx_GDI::ScPainterEx_GDI( HDC hDC, QRect& rect,  ScribusDoc* doc, bool gray ) : ScPainterExBase()
4360 cbradney 64
{
7478 jghali 65
        m_doc = doc;
4360 cbradney 66
        m_width = rect.width();
67
        m_height= rect.height();
6987 jghali 68
        m_strokeColor = ScColorShade( QColor(0,0,0), 100 );
69
        m_fillColor = ScColorShade( QColor(0,0,0), 100 );
70
        m_fillTrans = 1.0;
71
        m_strokeTrans = 1.0;
4360 cbradney 72
        m_fillRule = true;
6987 jghali 73
        m_fillMode = 1;
74
        m_lineWidth = 1.0;
4360 cbradney 75
        m_offset = 0;
76
        m_array.clear();
6987 jghali 77
        m_lineEnd = Qt::SquareCap;
78
        m_lineJoin = Qt::RoundJoin;
79
        m_fillGradient = VGradientEx(VGradientEx::linear);
80
        m_strokeGradient = VGradientEx(VGradientEx::linear);
8501 cbradney 81
        m_matrix = QMatrix();
6987 jghali 82
        // Grayscale conversion parameter
83
        m_convertToGray = gray;
4360 cbradney 84
        // Initialization of Windows GDI data
6987 jghali 85
        m_dc = hDC;
86
        m_hBmp = NULL;
87
        m_hMsImg32 = NULL;
88
        m_gradientFill = NULL;
89
        m_pathIsClosed = true;
90
        m_drawingClosedPath = false;
91
        m_deviceDimX = GetDeviceCaps(m_dc, PHYSICALWIDTH);
92
        m_deviceDimY = GetDeviceCaps(m_dc, PHYSICALHEIGHT);
93
        m_deviceResX = GetDeviceCaps(m_dc, LOGPIXELSX);
94
        m_deviceResY = GetDeviceCaps(m_dc, LOGPIXELSY);
4360 cbradney 95
#ifdef SC_USE_GDIPLUS
6987 jghali 96
        m_positionX = m_positionY = 0;
97
        m_graphics = new Gdiplus::Graphics( m_dc );
98
        m_graphics->SetCompositingMode( CompositingModeSourceOver );
99
        m_graphics->SetCompositingQuality( CompositingQualityHighQuality );
100
        m_graphics->SetSmoothingMode( SmoothingModeHighQuality );
101
        m_graphics->SetPageUnit( UnitPoint );
102
        m_graphicsPath = NULL;
4360 cbradney 103
#else
6987 jghali 104
        SetGraphicsMode( m_dc, GM_ADVANCED );
8523 cbradney 105
        SetPolyFillMode(m_dc, Qt::ALTERNATE);
4360 cbradney 106
        loadMsImg32();
107
#endif
108
        clear();
109
}
110
 
111
ScPainterEx_GDI::~ScPainterEx_GDI()
112
{
6987 jghali 113
        if ( m_hMsImg32 )
114
                FreeLibrary( m_hMsImg32 );
4360 cbradney 115
#ifdef SC_USE_GDIPLUS
6987 jghali 116
        if ( m_graphicsPath )
117
                delete m_graphicsPath;
118
        if ( m_graphics )
119
                delete m_graphics;
4360 cbradney 120
#endif
121
}
122
 
123
void ScPainterEx_GDI::loadMsImg32( void )
124
{
6987 jghali 125
        m_hMsImg32 = LoadLibrary( "msimg32.dll" );
126
        if( m_hMsImg32 )
127
                m_gradientFill = (gradientFillFunc) GetProcAddress( m_hMsImg32, "GradientFill" );
4360 cbradney 128
}
129
 
130
QColor ScPainterEx_GDI::transformColor( ScColorShade& colorShade, double trans )
131
{
132
        QColor c, color;
7478 jghali 133
        c = ScColorEngine::getShadeColor(colorShade.color, m_doc, colorShade.shade);
4360 cbradney 134
        color = qRgba( qRed(c.rgb()), qGreen(c.rgb()), qBlue(c.rgb()), qAlpha(trans * 255));
6987 jghali 135
        if ( m_convertToGray )
4360 cbradney 136
        {
137
                int grayLevel;
138
                QColor grayColor;
139
                grayLevel = 0.3 * color.red() + 0.59 * color.green() + 0.11 * color.blue();
140
                grayColor = qRgba( grayLevel, grayLevel, grayLevel, qAlpha(color.rgb()));
141
                color = grayColor;
142
        }
143
        return color;
144
}
145
 
146
void ScPainterEx_GDI::transformImage( QImage* image, uchar* data, int scan)
147
{
148
        int rgb, grey;
149
        int imageWidth = image->width();
150
        int imageHeight = image->height();
151
        QRgb* imageBits = (QRgb *) image->bits();
152
        QRgb*  pscani;
153
        uchar *pscand;
154
 
155
        pscand = data;
156
        for ( int j = 0; j < imageHeight; j++ )
157
        {
158
                pscani = (QRgb *) image->scanLine(j);
159
                for (int i = 0; i < imageWidth; i++ )
160
                {
161
                        rgb = pscani[i];
162
                        grey = 0.3 * qRed(rgb) + 0.59 * qGreen(rgb) + 0.11 * qBlue(rgb);
163
                        pscand[i] = grey;
164
                }
165
                pscand += scan;
166
        }
167
 
168
}
169
 
170
void ScPainterEx_GDI::begin()
171
{
172
}
173
 
174
void ScPainterEx_GDI::end()
175
{
176
#ifdef SC_USE_GDIPLUS
6987 jghali 177
        m_graphics->ResetTransform();
4360 cbradney 178
#else
6987 jghali 179
        ModifyWorldTransform(m_dc, NULL, MWT_IDENTITY);
4360 cbradney 180
#endif
181
}
182
 
183
void ScPainterEx_GDI::clear()
184
{
185
#ifdef SC_USE_GDIPLUS
186
        SolidBrush brush( Color(255,255,255) );
6987 jghali 187
        m_graphics->FillRectangle(&brush, 0, 0, m_width, m_height);
4360 cbradney 188
#else
189
        RECT rect;
190
        HBRUSH brush = CreateSolidBrush( RGB(255, 255, 255) );
191
        rect.bottom = 0;
192
        rect.left = 0;
193
        rect.right = m_width;
194
        rect.top = m_height;
6987 jghali 195
        FillRect(m_dc, &rect, brush);
4360 cbradney 196
        DeleteObject( brush );
197
#endif
198
}
199
 
200
void ScPainterEx_GDI::clear( ScColorShade &c )
201
{
202
        QColor color = transformColor( c, 1.0 );
203
#ifdef SC_USE_GDIPLUS
204
        QRgb cs = color.rgb();
205
        SolidBrush brush( Color(qAlpha(cs), qRed(cs), qGreen(cs),qBlue(cs)) );
6987 jghali 206
        m_graphics->FillRectangle(&brush, 0, 0, m_width, m_height);
4360 cbradney 207
#else
208
        RECT rect;
209
        HBRUSH brush = CreateSolidBrush( RGB( qRed(color.rgb()), qGreen(color.rgb()), qBlue(color.rgb()) ) );
210
        rect.bottom = 0;
211
        rect.left = 0;
212
        rect.right = m_width;
213
        rect.top = m_height;
6987 jghali 214
        FillRect(m_dc, &rect, brush);
4360 cbradney 215
        DeleteObject( brush );
216
#endif
217
}
218
 
8501 cbradney 219
const QMatrix ScPainterEx_GDI::worldMatrix()
4360 cbradney 220
{
221
        return m_matrix;
222
}
223
 
8501 cbradney 224
void ScPainterEx_GDI::setWorldMatrix( const QMatrix &mat )
4360 cbradney 225
{
226
        m_matrix = mat;
227
}
228
 
229
void ScPainterEx_GDI::transformPoint( const FPoint& in, FPoint& out )
230
{
231
        double x, y;
232
        x = in.x() * m_matrix.m11() + in.y() * m_matrix.m21() + m_matrix.dx();
233
        y = in.x() * m_matrix.m12() + in.y() * m_matrix.m22() + m_matrix.dy();
234
        out.setX( x );
235
        out.setY( y );
236
}
237
 
238
void ScPainterEx_GDI::transformPoints( const FPoint* ArrayIn, FPoint* ArrayOut, uint length )
239
{
240
        for( uint i = 0; i < length; i++ )
241
        {
242
                transformPoint( ArrayIn[i], ArrayOut[i] );
243
        }
244
}
245
 
246
void ScPainterEx_GDI::translate( double x, double y )
247
{
248
        m_matrix.translate(x, y);
249
}
250
 
251
void ScPainterEx_GDI::rotate( double r )
252
{
253
        m_matrix.rotate(r);
254
}
255
 
256
void ScPainterEx_GDI::scale( double x, double y )
257
{
258
        m_matrix.scale(x, y);
259
}
260
 
261
void ScPainterEx_GDI::moveTo( const double &x, const double &y )
262
{
6987 jghali 263
        FPoint pp( x, y );
4360 cbradney 264
        transformPoint( pp, pp );
265
#ifdef SC_USE_GDIPLUS
6987 jghali 266
        m_positionX = pp.x();
267
        m_positionY = pp.y();
4360 cbradney 268
#else
6987 jghali 269
        MoveToEx(m_dc, (int) pp.x(), (int) pp.y(), NULL);
4360 cbradney 270
#endif
271
}
272
 
273
void ScPainterEx_GDI::lineTo( const double &x, const double &y )
274
{
6987 jghali 275
        FPoint pp( x, y );
4360 cbradney 276
        transformPoint( pp, pp );
277
#ifdef SC_USE_GDIPLUS
6987 jghali 278
        m_graphicsPath->AddLine( (REAL) m_positionX, (REAL) m_positionY, pp.x(), pp.y() );
279
        m_positionX = pp.x();
280
        m_positionY = pp.y();
4360 cbradney 281
#else
6987 jghali 282
        LineTo(m_dc, (int) pp.x(), (int) pp.y());
4360 cbradney 283
#endif
284
}
285
 
286
void ScPainterEx_GDI::curveTo( FPoint p1, FPoint p2, FPoint p3 )
287
{
288
        FPoint fpoints[3];
6987 jghali 289
        fpoints[0].setXY( p1.x(), p1.y() );
290
        fpoints[1].setXY( p2.x(), p2.y() );
291
        fpoints[2].setXY( p3.x(), p3.y() );
4360 cbradney 292
        transformPoints( fpoints, fpoints, 3 );
293
#ifdef SC_USE_GDIPLUS
294
        double p1x = fpoints[0].x();
295
        double p1y = fpoints[0].y();
296
        double p2x = fpoints[1].x();
297
        double p2y = fpoints[1].y();
298
        double p3x = fpoints[2].x();
299
        double p3y = fpoints[2].y();
6987 jghali 300
        m_graphicsPath->AddBezier( (REAL) m_positionX, (REAL) m_positionY, p1x, p1y, p2x, p2y, p3x, p3y );
301
        m_positionX = p3x;
302
        m_positionY = p3y;
4360 cbradney 303
#else
304
        POINT points[3];
305
        points[0].x = fpoints[0].x();
306
        points[0].y = fpoints[0].y();
307
        points[1].x = fpoints[1].x();
308
        points[1].y = fpoints[1].y();
309
        points[2].x = fpoints[2].x();
310
        points[2].y = fpoints[2].y();
6987 jghali 311
        PolyBezierTo(m_dc, points, 3);
4360 cbradney 312
#endif
313
}
314
 
315
void ScPainterEx_GDI::newPath()
316
{
317
#ifdef SC_USE_GDIPLUS
6987 jghali 318
        if( m_graphicsPath )
319
                delete m_graphicsPath;
320
        m_graphicsPath = new Gdiplus::GraphicsPath();
321
        m_pathIsClosed = false;
322
        m_drawingClosedPath = false;
4360 cbradney 323
#else
6987 jghali 324
        bool done = BeginPath( m_dc );
4360 cbradney 325
        if(!done)
326
                cout << "BeginPath fuction has failed." << endl;
6987 jghali 327
        m_pathIsClosed = false;
328
        m_drawingClosedPath = false;
4360 cbradney 329
#endif
330
}
331
 
332
void ScPainterEx_GDI::setFillRule( bool fillRule )
333
{
334
        m_fillRule = fillRule;
335
}
336
 
337
void ScPainterEx_GDI::setFillMode( int fill )
338
{
6987 jghali 339
        m_fillMode = fill;
4360 cbradney 340
}
341
 
342
void ScPainterEx_GDI::setGradient(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc)
343
{
6987 jghali 344
        m_fillGradient.setType(mode);
345
        m_fillGradient.setOrigin(orig);
346
        m_fillGradient.setVector(vec);
347
        m_fillGradient.setFocalPoint(foc);
4360 cbradney 348
}
349
 
8501 cbradney 350
void ScPainterEx_GDI::setPattern( ScPattern* pattern, QMatrix& patternTransform )
6987 jghali 351
{
352
        m_pattern = pattern;
353
        m_patternTransform = patternTransform;
354
}
355
 
4360 cbradney 356
void ScPainterEx_GDI::fillTextPath()
357
{
358
        drawVPath( 0 );
359
}
360
 
361
void ScPainterEx_GDI::strokeTextPath()
362
{
6987 jghali 363
        if( m_lineWidth == 0 )
4360 cbradney 364
                return;
365
        drawVPath( 1 );
366
}
367
 
368
void ScPainterEx_GDI::fillPath()
369
{
370
#ifndef SC_USE_GDIPLUS
6987 jghali 371
        if( !m_pathIsClosed )
372
                EndPath( m_dc );
4360 cbradney 373
#endif
6987 jghali 374
        m_pathIsClosed = true;
375
        if( m_fillMode != 0)
4360 cbradney 376
                drawVPath( 0 );
377
}
378
 
379
void ScPainterEx_GDI::strokePath()
380
{
6987 jghali 381
        if( m_lineWidth == 0 )
4360 cbradney 382
                return;
6987 jghali 383
#ifndef SC_USE_GDIPLUS
384
        if( !m_pathIsClosed )
385
                EndPath( m_dc );
4360 cbradney 386
#endif
6987 jghali 387
        m_pathIsClosed = true;
4360 cbradney 388
        drawVPath( 1 );
389
}
390
 
391
ScColorShade ScPainterEx_GDI::pen()
392
{
6987 jghali 393
        return m_strokeColor;
4360 cbradney 394
}
395
 
396
ScColorShade ScPainterEx_GDI::brush()
397
{
6987 jghali 398
        return m_fillColor;
4360 cbradney 399
}
400
 
401
void ScPainterEx_GDI::setPen( const ScColorShade &c )
402
{
6987 jghali 403
        m_strokeColor = c;
4360 cbradney 404
}
405
 
406
void ScPainterEx_GDI::setPen( const ScColorShade &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
407
{
6987 jghali 408
        m_strokeColor = c;
409
        m_lineWidth = w;
410
        m_lineEnd = ca;
411
        m_lineJoin = jo;
8569 jghali 412
        double Dt = qMax(2*w, 1.0);
413
        double Da = qMax(6*w, 1.0);
8501 cbradney 414
        Q3ValueList<double> tmp;
4360 cbradney 415
        m_array.clear();
416
        m_offset = 0;
417
        switch (st)
418
        {
419
                case Qt::SolidLine:
420
                        break;
421
                case Qt::DashLine:
422
                        m_array.append(Da);
423
                        m_array.append(Dt);
424
                        break;
425
                case Qt::DotLine:
426
                        m_array.append(Dt);
427
#ifdef SC_USE_GDIPLUS
428
                        m_array.append(Dt);
429
#endif
430
                        break;
431
                case Qt::DashDotLine:
432
                        m_array.append(Da);
433
                        m_array.append(Dt);
434
                        m_array.append(Dt);
435
                        m_array.append(Dt);
436
                        break;
437
                case Qt::DashDotDotLine:
438
                        m_array.append(Da);
439
                        m_array.append(Dt);
440
                        m_array.append(Dt);
441
                        m_array.append(Dt);
442
                        m_array.append(Dt);
443
                        m_array.append(Dt);
444
                        break;
445
                default:
446
                        break;
447
        }
448
}
449
 
450
void ScPainterEx_GDI::setLineWidth( double w )
451
{
6987 jghali 452
        m_lineWidth = w;
4360 cbradney 453
}
454
 
455
void ScPainterEx_GDI::setPenOpacity( double op )
456
{
6987 jghali 457
        m_strokeTrans = op;
4360 cbradney 458
}
459
 
460
 
8501 cbradney 461
void ScPainterEx_GDI::setDash(const Q3ValueList<double>& array, double ofs)
4360 cbradney 462
{
463
        m_array = array;
464
        m_offset = ofs;
465
}
466
 
467
void ScPainterEx_GDI::setBrush( const ScColorShade &c )
468
{
6987 jghali 469
        m_fillColor = c;
4360 cbradney 470
}
471
 
472
void ScPainterEx_GDI::setBrushOpacity( double op )
473
{
6987 jghali 474
        m_fillTrans = op;
4360 cbradney 475
}
476
 
477
void ScPainterEx_GDI::setOpacity( double op )
478
{
6987 jghali 479
        m_fillTrans = op;
480
        m_strokeTrans = op;
4360 cbradney 481
}
482
 
483
void ScPainterEx_GDI::setFont( const QFont &f)
484
{
485
        m_font = f;
486
}
487
 
488
QFont ScPainterEx_GDI::font()
489
{
490
        return m_font;
491
}
492
 
493
void ScPainterEx_GDI::save()
494
{
6987 jghali 495
        m_stack.push( m_matrix );
4360 cbradney 496
#ifdef SC_USE_GDIPLUS
6987 jghali 497
        m_gStates.push( m_graphics->Save() );
4360 cbradney 498
#else
6987 jghali 499
        SaveDC( m_dc );
4360 cbradney 500
#endif
501
}
502
 
503
void ScPainterEx_GDI::restore()
504
{
6987 jghali 505
        m_matrix = m_stack.pop();
4360 cbradney 506
#ifdef SC_USE_GDIPLUS
6987 jghali 507
        m_graphics->Restore( m_gStates.pop() );
4360 cbradney 508
#else
6987 jghali 509
        RestoreDC( m_dc, -1 );
4360 cbradney 510
#endif
511
}
512
 
513
void ScPainterEx_GDI::setRasterOp( int   )
514
{
515
}
516
 
517
void ScPainterEx_GDI::drawVPath( int mode )
518
{
519
#ifdef SC_USE_GDIPLUS
520
        save();
521
        if (mode == 0)
522
        {
523
                if( m_fillRule )
6987 jghali 524
                        m_graphicsPath->SetFillMode( FillModeAlternate);
4360 cbradney 525
                else
6987 jghali 526
                        m_graphicsPath->SetFillMode( FillModeWinding);
527
                if (m_fillMode == ScPainterExBase::Gradient)
4360 cbradney 528
                {
6987 jghali 529
                        drawGradient( m_fillGradient );
4360 cbradney 530
                }
531
                else
532
                {
6987 jghali 533
                        QColor fillColor = transformColor(m_fillColor, 1.0);
8569 jghali 534
                        SolidBrush fill_brush( Color(m_fillTrans * 255, fillColor.red(), fillColor.green(), fillColor.blue()) );
6987 jghali 535
                        m_graphics->FillPath( &fill_brush, m_graphicsPath );
4360 cbradney 536
                }
537
        }
538
        else
539
        {
540
                double m11 = m_matrix.m11();
541
                double m12 = m_matrix.m12();
542
                double m21 = m_matrix.m21();
543
                double m22 = m_matrix.m22();
544
                double norm2 = m11 * m11 + m12 * m12 + m21 * m21 + m22 * m22;
6987 jghali 545
                double penScale = sqrt(norm2 / 2.0);
546
                double penWidth =  m_lineWidth * penScale;
547
                QColor strokeColor = transformColor( m_strokeColor, 1.0 );
8569 jghali 548
                SolidBrush stroke_brush( Color(m_strokeTrans * 255, strokeColor.red(), strokeColor.green(), strokeColor.blue()) );
4360 cbradney 549
                Pen stroke_pen( &stroke_brush, penWidth );
550
                REAL *dashes = NULL;
551
 
552
                if( m_array.count() > 0 )
553
                {
554
                        dashes = new REAL[ m_array.count() ];
8569 jghali 555
                        for( int i = 0; i < m_array.count();++ i )
4360 cbradney 556
                        {
6987 jghali 557
                                dashes[i] = (REAL) ( m_array[i] / (double) m_lineWidth );
4360 cbradney 558
                                // The following lines are needed so that gdi+ rendering matches the libart one
6987 jghali 559
                                if( m_lineEnd == Qt::RoundCap || m_lineEnd == Qt::SquareCap )
4360 cbradney 560
                                {
561
                                        if( (i % 2) == 0 )
562
                                                dashes[i] = dashes[i] + 1.0;
563
                                        else
564
                                                dashes[i] = dashes[i] - 1.0;
565
                                }
566
                        }
567
                        // The following two lines are needed so that gdi+ rendering matches the libart one
6987 jghali 568
                        if( m_lineEnd == Qt::SquareCap && m_array.count() >= 2)
4360 cbradney 569
                                stroke_pen.SetDashOffset( dashes[1]/2 );
570
                        stroke_pen.SetDashPattern( dashes, m_array.count() );
571
                }
6987 jghali 572
                if( m_lineEnd == Qt::RoundCap )
4360 cbradney 573
                        stroke_pen.SetLineCap( LineCapRound, LineCapRound, DashCapRound );
6987 jghali 574
                else if( m_lineEnd == Qt::SquareCap )
4360 cbradney 575
                        stroke_pen.SetLineCap( LineCapSquare, LineCapSquare, DashCapFlat );
6987 jghali 576
                else if( m_lineEnd == Qt::FlatCap && m_array.count() == 0 && m_drawingClosedPath )
4360 cbradney 577
                        stroke_pen.SetLineCap( LineCapSquare, LineCapSquare, DashCapFlat );
6987 jghali 578
                else if( m_lineEnd == Qt::FlatCap )
4360 cbradney 579
                        stroke_pen.SetLineCap( LineCapFlat, LineCapFlat, DashCapFlat );
6987 jghali 580
                if( m_lineJoin == Qt::RoundJoin )
4360 cbradney 581
                        stroke_pen.SetLineJoin( LineJoinRound );
6987 jghali 582
                else if( m_lineJoin == Qt::BevelJoin )
4360 cbradney 583
                        stroke_pen.SetLineJoin( LineJoinBevel );
6987 jghali 584
                else if( m_lineJoin == Qt::MiterJoin )
4360 cbradney 585
                        stroke_pen.SetLineJoin( LineJoinMiter );
586
 
6987 jghali 587
                m_graphics->DrawPath( &stroke_pen, m_graphicsPath );
4360 cbradney 588
                if( dashes )
589
                        delete [] dashes;
590
        }
591
        restore();
592
#else
593
        int dcState;
6987 jghali 594
        dcState = SaveDC( m_dc );
4360 cbradney 595
        if (mode == 0)
596
        {
597
                if( m_fillRule )
8523 cbradney 598
                        SetPolyFillMode(m_dc, Qt::ALTERNATE);
4360 cbradney 599
                else
6987 jghali 600
                        SetPolyFillMode(m_dc, WINDING);
601
                if (m_fillMode == ScPainterExBase::Gradient)
4360 cbradney 602
                {
6987 jghali 603
                        drawGradient( m_fillGradient );
4360 cbradney 604
                }
605
                else
606
                {
6987 jghali 607
                        QColor fillColor = transformColor( m_fillColor, 1.0 );
4360 cbradney 608
                        HBRUSH brush = CreateSolidBrush( RGB( qRed(fillColor.rgb()), qGreen(fillColor.rgb()), qBlue(fillColor.rgb()) ) );
6987 jghali 609
                        HGDIOBJ obj = SelectObject(m_dc, brush);
610
                        FillPath(m_dc);
611
                        SelectObject(m_dc, obj);
4360 cbradney 612
                        DeleteObject(brush);
613
                }
614
        }
615
        else
616
        {
617
                DWORD penStyle = PS_GEOMETRIC;
618
                DWORD penWidth = 0;
619
                LOGBRUSH logBrush;
620
                DWORD *dashes = NULL;
621
 
6987 jghali 622
                QColor strokeColor = transformColor( m_strokeColor, 1.0 );
4360 cbradney 623
                logBrush.lbStyle = BS_SOLID;
624
                logBrush.lbColor = RGB( qRed(strokeColor.rgb()), qGreen(strokeColor.rgb()), qBlue(strokeColor.rgb()) );
625
                logBrush.lbHatch = 0;
626
 
627
                double m11 = m_matrix.m11();
628
                double m12 = m_matrix.m12();
629
                double m21 = m_matrix.m21();
630
                double m22 = m_matrix.m22();
631
                double norm2 = m11 * m11 + m12 * m12 + m21 * m21 + m22 * m22;
6987 jghali 632
                double penScale = sqrt(norm2 /2.0);
633
                penWidth = (int) (m_lineWidth * penScale);
4360 cbradney 634
 
635
                if( m_array.count() > 0 )
636
                {
637
                        dashes = new DWORD[ m_array.count() ];
638
                        for( uint i = 0; i < m_array.count();++ i )
639
                        {
640
                                dashes[i] = (DWORD) (m_array[i] * penScale);
641
                        }
642
                        penStyle = penStyle | PS_USERSTYLE;
643
                }
644
                if( PLineEnd == Qt::RoundCap )
645
                        penStyle = penStyle | PS_ENDCAP_ROUND;
646
                else if( PLineEnd == Qt::SquareCap )
647
                        penStyle = penStyle | PS_ENDCAP_SQUARE;
6987 jghali 648
                else if( PLineEnd == Qt::FlatCap && m_array.count() == 0 && m_drawingClosedPath )
4360 cbradney 649
                        penStyle = penStyle | PS_ENDCAP_SQUARE;
650
                else if( PLineEnd == Qt::FlatCap )
651
                        penStyle = penStyle | PS_ENDCAP_FLAT;
6987 jghali 652
                if( m_lineJoin == Qt::RoundJoin )
4360 cbradney 653
                        penStyle = penStyle | PS_JOIN_ROUND;
6987 jghali 654
                else if( m_lineJoin == Qt::BevelJoin )
4360 cbradney 655
                        penStyle = penStyle | PS_JOIN_BEVEL;
6987 jghali 656
                else if( m_lineJoin == Qt::MiterJoin )
4360 cbradney 657
                        penStyle = penStyle | PS_JOIN_MITER;
658
 
659
                HPEN pen = ExtCreatePen(penStyle, penWidth, &logBrush, m_array.count(), dashes);
6987 jghali 660
                HGDIOBJ obj = SelectObject( m_dc, pen);
661
                StrokePath( m_dc );
662
                SelectObject( m_dc, obj);
4360 cbradney 663
                DeleteObject( pen);
664
                if( dashes )
665
                        delete [] dashes;
666
        }
6987 jghali 667
        RestoreDC( m_dc, dcState );
4360 cbradney 668
#endif
669
}
670
 
671
void ScPainterEx_GDI::setClipPath()
672
{
673
#ifdef SC_USE_GDIPLUS
6987 jghali 674
        m_graphics->SetClip( m_graphicsPath, CombineModeIntersect );
4360 cbradney 675
#else
6987 jghali 676
        SelectClipPath( m_dc, RGN_AND );
4360 cbradney 677
#endif
678
}
679
 
4989 cbradney 680
void ScPainterEx_GDI::drawImage( ScImage *image, ScPainterExBase::ImageMode mode )
4360 cbradney 681
{
682
#ifdef SC_USE_GDIPLUS
683
        FPoint ulp( 0, 0 );
6987 jghali 684
        FPoint urp( image->width(), 0 );
685
        FPoint blp( 0, image->height() );
4360 cbradney 686
        transformPoint( ulp, ulp );
687
        transformPoint( blp, blp );
688
        transformPoint( urp, urp );
689
        Point destinationPoint[] = { Point(ulp.x(), ulp.y()), Point(urp.x(), urp.y()), Point(blp.x(), blp.y()) };
690
        ColorMatrix colorMatrix = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
691
                                                           0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
692
                               0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
6987 jghali 693
                               0.0f, 0.0f, 0.0f, m_fillTrans, 0.0f,
4360 cbradney 694
                               0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
6987 jghali 695
        if ( m_convertToGray )
4360 cbradney 696
        {
697
                colorMatrix.m[0][0] = colorMatrix.m[0][1] = colorMatrix.m[0][2] = (REAL) 0.3;
698
                colorMatrix.m[1][0] = colorMatrix.m[1][1] = colorMatrix.m[1][2] = (REAL) 0.59;
699
                colorMatrix.m[2][0] = colorMatrix.m[2][1] = colorMatrix.m[2][2] = (REAL) 0.11;
700
        }
701
        ImageAttributes imageAtt;
702
        imageAtt.SetColorMatrix(&colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
8569 jghali 703
        Bitmap bitmap( image->width(), image->height(), 4 * image->width(), PixelFormat32bppARGB, (uchar*) image->qImage().bits() );
6987 jghali 704
        m_graphics->DrawImage( &bitmap, destinationPoint, 3, 0, 0, image->width(), image->height(), UnitPixel, &imageAtt );
4360 cbradney 705
#else
706
        save();
707
        int usage = 0;
708
        unsigned char* data = NULL;
5624 jghali 709
        unsigned char* imageData = image->qImage().bits();
4360 cbradney 710
        XFORM xform = { m_matrix.m11(), m_matrix.m12(), m_matrix.m21(), m_matrix.m22(), m_matrix.dx(), m_matrix.dy() } ;
6987 jghali 711
        ModifyWorldTransform(m_dc, &xform, MWT_LEFTMULTIPLY);
4360 cbradney 712
        BITMAPINFO256 bmpInfo;
713
        ZeroMemory( &bmpInfo, sizeof(bmpInfo));
714
        bmpInfo.bmiHeader.biSize = sizeof( bmpInfo.bmiHeader );
715
        bmpInfo.bmiHeader.biWidth = image->width();
716
        bmpInfo.bmiHeader.biHeight = -image->height();
717
        bmpInfo.bmiHeader.biPlanes = 1;
718
        bmpInfo.bmiHeader.biBitCount = 32;
719
        bmpInfo.bmiHeader.biCompression = BI_RGB;
720
        bmpInfo.bmiHeader.biSizeImage = 0;
6987 jghali 721
        if ( m_convertToGray )
4360 cbradney 722
        {
723
                int scanline = (image->width() + image->width() % 4);
724
                bmpInfo.bmiHeader.biBitCount = 8;
725
                bmpInfo.bmiHeader.biSizeImage = scanline * image->height();
726
                for( int i = 0; i < 256; i++ )
727
                {
728
                        bmpInfo.bmiColors[i].rgbRed = i;
729
                        bmpInfo.bmiColors[i].rgbGreen = i;
730
                        bmpInfo.bmiColors[i].rgbBlue = i;
731
                }
5624 jghali 732
                QImage imTemp = image->qImage();
4360 cbradney 733
                data = new uchar[bmpInfo.bmiHeader.biSizeImage];
5624 jghali 734
                transformImage( &imTemp, data, scanline );
4360 cbradney 735
                imageData = data;
736
                usage = DIB_RGB_COLORS;
737
        }
6987 jghali 738
        StretchDIBits( m_dc, 0, 0 , image->width(), image->height(), 0, 0, image->width(), image->height(),
739
                imageData, (BITMAPINFO*) &bmpInfo, usage, SRCCOPY );
4360 cbradney 740
        if( data )
741
                delete[] data;
742
        restore();
743
#endif
744
}
745
 
746
void ScPainterEx_GDI::setupPolygon(FPointArray *points, bool closed)
747
{
748
        bool nPath = true;
749
        FPoint np, np1, np2, np3;
750
        if (points->size() > 3)
751
        {
752
                newPath();
753
                for (uint poi=0; poi<points->size()-3; poi += 4)
754
                {
755
                        if (points->point(poi).x() > 900000)
756
                        {
757
                                nPath = true;
758
                                continue;
759
                        }
760
                        if (nPath)
761
                        {
762
                                np = points->point(poi);
763
#ifdef SC_USE_GDIPLUS
6987 jghali 764
                                m_graphicsPath->StartFigure();
4360 cbradney 765
#endif
766
                                moveTo( np.x(), np.y() );
767
                                nPath = false;
768
                        }
769
                        np = points->point(poi);
770
                        np1 = points->point(poi+1);
771
                        np2 = points->point(poi+3);
772
                        np3 = points->point(poi+2);
773
                        if ((np == np1) && (np2 == np3))
774
                                lineTo( np3.x(), np3.y() );
775
                        else
776
                                curveTo(np1, np2, np3);
777
                }
778
                if (closed)
779
                {
780
#ifndef SC_USE_GDIPLUS
6987 jghali 781
                        EndPath( m_dc );
4360 cbradney 782
#endif
6987 jghali 783
                        m_pathIsClosed = true;
784
                        m_drawingClosedPath = true;
4360 cbradney 785
                }
786
        }
787
}
788
 
789
void ScPainterEx_GDI::setupTextPolygon(FPointArray *points)
790
{
791
        bool nPath = true;
792
        FPoint np, np1, np2, np3;
793
        if (points->size() > 3)
794
        {
795
                newPath();
796
                for (uint poi=0; poi<points->size()-3; poi += 4)
797
                {
798
                        if (points->point(poi).x() > 900000)
799
                        {
800
                                nPath = true;
801
                                continue;
802
                        }
803
                        if (nPath)
804
                        {
805
                                np = points->point(poi);
806
#ifdef SC_USE_GDIPLUS
6987 jghali 807
                                m_graphicsPath->CloseFigure();
808
                                m_graphicsPath->StartFigure();
4360 cbradney 809
#endif
6987 jghali 810
                                moveTo( np.x(), np.y() );
4360 cbradney 811
                                nPath = false;
812
                        }
6987 jghali 813
                        np.setXY( points->point(poi).x(), points->point(poi).y() );
814
                        np1.setXY( points->point(poi+1).x(), points->point(poi+1).y() );
815
                        np2.setXY( points->point(poi+3).x(), points->point(poi+3).y() );
816
                        np3.setXY( points->point(poi+2).x(), points->point(poi+2).y() );
4360 cbradney 817
                        if ((np == np1) && (np2 == np3))
818
                                lineTo( np3.x(), np3.y() );
819
                        else
820
                                curveTo( np1, np2, np3 );
821
                }
822
#ifdef SC_USE_GDIPLUS
6987 jghali 823
                m_graphicsPath->CloseFigure();
4360 cbradney 824
#else
6987 jghali 825
        EndPath( m_dc );
4360 cbradney 826
#endif
6987 jghali 827
                m_pathIsClosed = true;
4360 cbradney 828
        }
829
}
830
 
831
void ScPainterEx_GDI::drawPolygon()
832
{
833
        fillPath();
834
}
835
 
836
void ScPainterEx_GDI::drawPolyLine()
837
{
838
        strokePath();
839
}
840
 
841
void ScPainterEx_GDI::drawLine(FPoint start, FPoint end)
842
{
843
        newPath();
844
        moveTo(start.x(), start.y());
845
        lineTo(end.x(), end.y());
846
        strokePath();
847
}
848
 
849
void ScPainterEx_GDI::drawRect(double x, double y, double w, double h)
850
{
851
        newPath();
852
        moveTo( x, y );
853
        lineTo( x+w, y );
854
        lineTo( x+w, y+h );
855
        lineTo( x, y+h );
856
        lineTo( x, y );
857
#ifndef SC_USE_GDIPLUS
6987 jghali 858
        EndPath(m_dc);
4360 cbradney 859
#endif
6987 jghali 860
        m_pathIsClosed = true;
861
        m_drawingClosedPath = true;
4360 cbradney 862
        fillPath();
863
        strokePath();
864
}
865
 
866
void ScPainterEx_GDI::drawGradient( VGradientEx& gradient )
867
{
868
        QRect clipPathRect;
869
#ifdef SC_USE_GDIPLUS
870
        save();
871
        setClipPath();
872
        getClipPathDimensions( clipPathRect );
873
        if ( gradient.type() == VGradientEx::linear )
874
                drawLinearGradient( gradient, clipPathRect );
875
        else if ( gradient.type() == VGradientEx::radial )
876
                drawCircularGradient( gradient, clipPathRect );
877
        restore();
878
#else
6987 jghali 879
        SaveDC( m_dc );
880
        SelectClipPath( m_dc, RGN_COPY );
4360 cbradney 881
        getClipPathDimensions( clipPathRect );
6987 jghali 882
        bool haveMsImg32 = ( m_hMsImg32 != NULL && m_gradientFill != NULL );
4360 cbradney 883
        if ( gradient.type() == VGradientEx::linear && haveMsImg32 )
884
                drawLinearGradient_GradientFill( gradient, clipPathRect );
885
        else if ( gradient.type() == VGradientEx::linear )
4989 cbradney 886
                drawLinearGradient( gradient, clipPathRect );
4360 cbradney 887
        else if (gradient.type() == VGradientEx::radial)
888
                drawCircularGradient( gradient, clipPathRect );
6987 jghali 889
        RestoreDC( m_dc, -1 );
4360 cbradney 890
#endif
891
}
892
 
893
void ScPainterEx_GDI::drawLinearGradient( VGradientEx& gradient, const QRect& rect )
894
{
895
#ifdef SC_USE_GDIPLUS
896
        Matrix matrix;
897
        int index = 0;
898
        int numElements;
899
        int r, g, b, a;
900
        double cosa, sina;
901
        double length, scale;
902
        double x1, y1, x2, y2, dx, dy;
903
        int clipBoxWidth, clipBoxHeight, maxDim;
8501 cbradney 904
        Q3PtrVector<VColorStopEx> colorStops = gradient.colorStops();
4360 cbradney 905
        VColorStopEx stop( *colorStops[0] );
906
        FPoint p1, p1a, p2, p2a;
907
        QColor color;
908
 
909
        if ( gradient.Stops() < 2 )
910
                return;
911
 
912
        clipBoxWidth = rect.width();
913
        clipBoxHeight = rect.height();
8335 jghali 914
        maxDim = sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) ) * 2;
4360 cbradney 915
        if ( maxDim <= 0 )
916
                return;
917
 
6987 jghali 918
        x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
919
        y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
920
        x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
921
        y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
4360 cbradney 922
        p1.setXY( x1, y1 );
923
        p2.setXY( x2, y2 );
924
 
925
        dx = ( p2.x() - p1.x() );
926
        dy = ( p2.y() - p1.y() );
927
        length = sqrt(( dx * dx + dy * dy ));
928
        if ( length == 0.0 )
929
                scale = 1.0;
930
        else
931
                scale = 1.0 / length;
932
        cosa = dx * scale;
933
        sina = dy * scale;
934
 
935
        p1a.setXY( p1.x() - cosa * maxDim, p1.y() - sina * maxDim );
936
        p2a.setXY( p2.x() + cosa * maxDim, p2.y() + sina * maxDim );
937
 
938
        numElements = gradient.Stops() + 2;
939
        Color *colors = new Color[numElements];
940
        REAL  *positions = new REAL[numElements];
941
 
942
        stop = *colorStops[0];
943
        color = transformColor( ScColorShade(stop.color, stop.shade), 1.0 );
8569 jghali 944
        colors[0] = Color(stop.opacity * 255, color.red(), color.green(), color.blue());
4360 cbradney 945
        positions[0] = 0.0;
946
 
947
        stop = *colorStops[gradient.Stops() - 1];
948
        color = transformColor( ScColorShade(stop.color, stop.shade), 1.0 );
8569 jghali 949
        colors[numElements - 1] = Color(stop.opacity * 255, color.red(), color.green(), color.blue());
4360 cbradney 950
        positions[numElements - 1] = 1.0;
951
 
952
        for( uint index = 0 ; index < gradient.Stops(); index++)
953
        {
954
                stop = *colorStops[index];
955
                color = transformColor( ScColorShade(stop.color, stop.shade), 1.0 );
8569 jghali 956
                r = color.red();
957
                g = color.green();
958
                b = color.blue();
4360 cbradney 959
                a = stop.opacity * 255;
960
                colors[index + 1] = Color(a, r, g, b);
961
                positions[index + 1] = ( stop.rampPoint * length + maxDim ) / ( length + 2 * maxDim );
962
        }
963
        LinearGradientBrush gradientBrush( PointF( p1a.x(), p1a.y() ) ,
964
                                                                           PointF( p2a.x(), p2a.y() ),
965
                                                                           colors[0], colors[numElements - 1] );
966
        gradientBrush.SetInterpolationColors(colors, positions, numElements);
6987 jghali 967
        m_graphics->FillPath( &gradientBrush, m_graphicsPath );
4360 cbradney 968
 
969
        delete[] colors;
970
        delete[] positions;
971
#else
972
        XFORM xform;
973
        int xCurrent;
974
        int increment;
975
        int r1, g1, b1, a1;
976
        int r2, g2, b2, a2;
977
        int r3, g3, b3, a3;
978
        double colorCoeff;
979
        double cosa, sina;
980
        double ramp1, ramp2;
981
        double scale1, scale2;
982
        double length, scale;
983
        double x1, y1, x2, y2, dx, dy;
984
        int clipBoxWidth, clipBoxHeight, maxDim;
8501 cbradney 985
        Q3PtrVector<VColorStopEx> colorStops = gradient.colorStops();
4360 cbradney 986
        VColorStopEx stop1( *colorStops[0] );
987
        VColorStopEx stop2( *colorStops[0] );
988
        FPoint p1, p1a, p2, p2a;
989
        QColor color;
990
        int rgb;
991
 
992
        if ( gradient.Stops() < 2 )
993
                return;
994
 
995
        clipBoxWidth = rect.width();
996
        clipBoxHeight = rect.height();
997
        maxDim = sqrt( clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight ) * 2;
998
        if ( maxDim <= 0 ) return;
999
 
1000
        scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m12() * m_matrix.m12() );
1001
        scale2 = sqrt( m_matrix.m21() * m_matrix.m21() + m_matrix.m22() * m_matrix.m22() );
1002
        increment = (int) max( scale1, scale2 );
1003
        increment = (increment < 2) ? 2 : increment;
1004
 
6987 jghali 1005
        x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
1006
        y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
1007
        x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
1008
        y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
4360 cbradney 1009
        p1.setXY( x1, y1 );
1010
        p2.setXY( x2, y2 );
1011
 
1012
        dx = ( p2.x() - p1.x() );
1013
        dy = ( p2.y() - p1.y() );
1014
        length = sqrt(( dx * dx + dy * dy ));
1015
        if ( length == 0.0 )
1016
                scale = 1.0;
1017
        else
1018
                scale = 1.0 / length;
1019
        cosa = dx * scale;
1020
        sina = dy * scale;
1021
 
1022
        ramp1 = stop1.rampPoint;
1023
        color =  transformColor( ScColorShade(stop1.color, stop1.shade), 1.0 );
1024
        r1 = color.red();
1025
        g1 = color.green();
1026
        b1 = color.blue();
1027
        a1 = stop1.opacity * 255;
1028
        drawRectangleStrip( m_matrix.dx(), m_matrix.dy(), maxDim, maxDim, r1, g1, b1, a1);
1029
 
1030
        xform.eM11 = cosa;
1031
        xform.eM12 = sina;
1032
        xform.eM21 = -sina;
1033
        xform.eM22 = cosa;
1034
        xform.eDx = x1;
1035
        xform.eDy = y1;
6987 jghali 1036
        ModifyWorldTransform(m_dc, &xform, MWT_LEFTMULTIPLY);
4360 cbradney 1037
 
1038
        for( uint index = 1; index < gradient.Stops(); index++)
1039
        {
1040
                stop2 = *colorStops[index];
1041
                ramp2 = stop2.rampPoint;
1042
                color =  transformColor( ScColorShade(stop2.color, stop2.shade), 1.0 );
1043
                r2 = color.red();
1044
                g2 = color.green();
1045
                b2 = color.blue();
1046
                a2 = stop2.opacity * 255;
1047
                int xMin = length * ramp1;
1048
                int xMax = length * ramp2;
4989 cbradney 1049
                int r4= -1, b4= -1, g4= -1, a4= -1;
4360 cbradney 1050
                for( xCurrent = xMin; xCurrent < xMax; xCurrent += increment )
1051
                {
1052
                        colorCoeff = ( xCurrent - xMin ) / ( (double) xMax - xMin ) ;
1053
                        r3 = ( 1 - colorCoeff ) * r1 + colorCoeff * r2;
1054
                        g3 = ( 1 - colorCoeff ) * g1 + colorCoeff * g2;
1055
                        b3 = ( 1 - colorCoeff ) * b1 + colorCoeff * b2;
1056
                        a3 = ( 1 - colorCoeff ) * a1 + colorCoeff * a2;
4989 cbradney 1057
                        if( (r3 != r4) || (g3 != g4) || (b3 != b4) )
1058
                        {
1059
                                drawRectangleStrip( xCurrent, -maxDim/2, maxDim, maxDim, r3, g3, b3, a3 );
1060
                                r4 = r3;
1061
                                g4 = g3;
1062
                                b4 = b3;
1063
                        }
4360 cbradney 1064
                }
1065
                stop1 = stop2;
1066
                ramp1 = ramp2;
1067
                r1 = r2;
1068
                g1 = g2;
1069
                b1 = b2;
1070
                a1 = a2;
1071
        }
1072
#endif
1073
}
1074
 
1075
void ScPainterEx_GDI::drawLinearGradient_GradientFill( VGradientEx& gradient, const QRect& rect )
1076
{
1077
        XFORM xform;
1078
        int r1, g1, b1;
1079
        int r2, g2, b2;
1080
        double cosa, sina;
1081
        double ramp1, ramp2;
1082
        double length, scale;
1083
        double x1, y1, x2, y2, dx, dy;
1084
        int clipBoxWidth, clipBoxHeight, maxDim;
8501 cbradney 1085
        Q3PtrVector<VColorStopEx> colorStops = gradient.colorStops();
4360 cbradney 1086
        VColorStopEx stop1( *colorStops[0] );
1087
        VColorStopEx stop2( *colorStops[0] );
4989 cbradney 1088
        FPoint p1, p2;
4360 cbradney 1089
        QColor color;
1090
 
1091
        if ( gradient.Stops() < 2 )
1092
                return;
1093
 
1094
        clipBoxWidth = rect.width();
1095
        clipBoxHeight = rect.height();
8335 jghali 1096
        maxDim = sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) ) * 2;
4360 cbradney 1097
        if ( maxDim <= 0 ) return;
1098
 
6987 jghali 1099
        x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
1100
        y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
1101
        x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
1102
        y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
4360 cbradney 1103
        p1.setXY( x1, y1 );
1104
        p2.setXY( x2, y2 );
1105
 
1106
        dx = ( p2.x() - p1.x() );
1107
        dy = ( p2.y() - p1.y() );
1108
        length = sqrt(( dx * dx + dy * dy ));
1109
        if ( length == 0.0 )
1110
                scale = 1.0;
1111
        else
1112
                scale = 1.0 / length;
1113
        cosa = dx * scale;
1114
        sina = dy * scale;
1115
 
1116
        xform.eM11 = cosa;
1117
        xform.eM12 = sina;
1118
        xform.eM21 = -sina;
1119
        xform.eM22 = cosa;
1120
        xform.eDx = x1;
1121
        xform.eDy = y1;
6987 jghali 1122
        ModifyWorldTransform(m_dc, &xform, MWT_LEFTMULTIPLY);
4360 cbradney 1123
 
1124
        x1 = -maxDim;
1125
        stop1 = *colorStops[0];
1126
        ramp1 = stop1.rampPoint;
1127
        color =  transformColor( ScColorShade(stop1.color, stop1.shade), 1.0 );
1128
        r1 = color.red();
1129
        g1 = color.green();
1130
        b1 = color.blue();
1131
 
1132
        int numMeshes = colorStops.size() + 1;
1133
        int numVertices = numMeshes * 2;
1134
        TRIVERTEX* vertices = new TRIVERTEX[numVertices];
1135
        GRADIENT_RECT* meshes = new GRADIENT_RECT[numMeshes];
1136
 
1137
        vertices[0].x = x1;
1138
        vertices[0].y = -maxDim / 2;
1139
        vertices[0].Red = r1 << 8;
1140
        vertices[0].Green = g1 << 8;
1141
        vertices[0].Blue = b1 << 8;
1142
        vertices[0].Alpha = 0;
1143
        meshes[0].UpperLeft = 0;
1144
 
1145
        uint vIndex = 1;
1146
        for( uint index = 0; index < gradient.Stops(); index++, vIndex += 2)
1147
        {
1148
                stop2 = *colorStops[index];
1149
                ramp2 =  stop2.rampPoint;
1150
                color =  transformColor( ScColorShade(stop2.color, stop2.shade), 1.0 );
1151
                r2 = color.red() << 8;
1152
                g2 = color.green() << 8;
1153
                b2 = color.blue() << 8;
1154
                x2 = /*maxDim +*/ length * ramp2;
1155
                vertices[vIndex].x = x2;
1156
                vertices[vIndex].y = maxDim / 2;
1157
                vertices[vIndex].Red = r2;
1158
                vertices[vIndex].Green = g2;
1159
                vertices[vIndex].Blue = b2;
1160
                vertices[vIndex].Alpha = 0;
1161
                vertices[vIndex + 1].x = x2;
1162
                vertices[vIndex + 1].y = -maxDim / 2;
1163
                vertices[vIndex + 1].Red = r2;
1164
                vertices[vIndex + 1].Green = g2;
1165
                vertices[vIndex + 1].Blue = b2;
1166
                vertices[vIndex + 1].Alpha = 0;
1167
                meshes[index].LowerRight = vIndex;
1168
                meshes[index + 1].UpperLeft = vIndex + 1;
1169
        }
1170
 
1171
        vertices[numVertices - 1].x = length + maxDim;
1172
        vertices[numVertices - 1].y = maxDim / 2;
1173
        vertices[numVertices - 1].Red = r2 << 8;
1174
        vertices[numVertices - 1].Green = g2 << 8;
1175
        vertices[numVertices - 1].Blue = b2 << 8;
1176
        vertices[numVertices - 1].Alpha = 0;
1177
        meshes[numMeshes - 1].LowerRight = numVertices - 1;
1178
 
1179
        // Finally call the gradient fill function
6987 jghali 1180
        (*m_gradientFill)( m_dc, vertices, numVertices, meshes, numMeshes, GRADIENT_FILL_RECT_H );
4360 cbradney 1181
 
1182
        // Delete used arrays
1183
        delete[] vertices;
1184
        delete[] meshes;
1185
}
1186
 
1187
void ScPainterEx_GDI::drawRectangleStrip( int x, int y, int w, int h, int r, int g, int b, int a )
1188
{
1189
#ifndef SC_USE_GDIPLUS
6987 jghali 1190
        SaveDC( m_dc );
4360 cbradney 1191
        HPEN hPen = CreatePen( PS_NULL, 0, RGB(255,255,255));
1192
        HBRUSH hBrush = CreateSolidBrush( RGB(r, g, b));
6987 jghali 1193
        HGDIOBJ obj1 = SelectObject( m_dc, hPen );
1194
        HGDIOBJ obj2 = SelectObject( m_dc, hBrush );
1195
        Rectangle( m_dc, x, y, x + w, y + h );
1196
        SelectObject( m_dc, obj2 );
1197
        SelectObject( m_dc, obj1 );
4360 cbradney 1198
        DeleteObject( hBrush );
1199
        DeleteObject( hPen );
6987 jghali 1200
        RestoreDC( m_dc, -1 );
4360 cbradney 1201
#endif
1202
}
1203
 
1204
void ScPainterEx_GDI::drawCircularGradient( VGradientEx& gradient, const QRect& rect )
1205
{
1206
#ifdef SC_USE_GDIPLUS
1207
        int offset = 0;
1208
        int numElements;
1209
        int r, g, b, a;
1210
        int clipBoxWidth, clipBoxHeight, maxDim;
8501 cbradney 1211
        Q3PtrVector<VColorStopEx> colorStops = gradient.colorStops();
4360 cbradney 1212
        VColorStopEx stop( *colorStops[0] );
1213
        QColor color;
1214
 
1215
        clipBoxWidth = rect.width();
1216
        clipBoxHeight = rect.height();
8335 jghali 1217
        maxDim = sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) ) * 2;
4360 cbradney 1218
        if ( maxDim <= 0 ) return;
1219
 
1220
        FPoint pc( gradient.origin().x(), gradient.origin().y() );
6987 jghali 1221
        FPoint pcz( gradient.origin().x(), gradient.origin().y() );
4360 cbradney 1222
        FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
6987 jghali 1223
        FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
4360 cbradney 1224
        FPoint pv( gradient.vector().x(), gradient.vector().y() );
1225
        transformPoint( pc, pc );
1226
        transformPoint( pf, pf );
1227
        transformPoint( pv, pv );
1228
        transformPoint( pcz, pcz );
1229
        transformPoint( pfz, pfz );
1230
        double cx = pcz.x();
1231
        double cy = pcz.y();
1232
        double fx = pfz.x();
1233
        double fy = pfz.y();
1234
        double rad = sqrt( pow(pv.x() - pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
1235
 
1236
        numElements = gradient.Stops() + 2;
1237
        Color *colors = new Color[numElements];
1238
        REAL  *positions = new REAL[numElements];
1239
 
1240
        stop = *colorStops[ 0 ];
1241
        color = transformColor( ScColorShade(stop.color, stop.shade), stop.opacity);
8569 jghali 1242
        colors[numElements - 1] = Color(stop.opacity * 255, color.red(), color.green(), color.blue());
4360 cbradney 1243
        positions[numElements - 1] = 1.0;              
1244
 
1245
        stop = *colorStops[ gradient.Stops() - 1 ];
1246
        color = transformColor( ScColorShade(stop.color, stop.shade), stop.opacity);
8569 jghali 1247
        colors[0] = Color(stop.opacity * 255, color.red(), color.green(), color.blue());
4360 cbradney 1248
        positions[0] = 0.0;
1249
 
1250
        for( uint index = 0 ; index < gradient.Stops() ; index++)
1251
        {
1252
                stop = *colorStops[index];
1253
                color = transformColor( ScColorShade(stop.color, stop.shade), 1.0 );
8569 jghali 1254
                r = color.red();
1255
                g = color.green();
1256
                b = color.blue();
4360 cbradney 1257
                a = stop.opacity * 255;
1258
                colors[gradient.Stops() - index] = Color(a, r, g, b);
1259
                positions[gradient.Stops() - index] = 1 - 2 * (stop.rampPoint * rad) / (double) maxDim;
1260
        }
1261
 
1262
        GraphicsPath gradientPath;
1263
        gradientPath.AddEllipse( cx - maxDim/2, cy - maxDim/2, maxDim, maxDim );
1264
        PathGradientBrush gradientBrush( &gradientPath );
1265
        gradientBrush.SetCenterPoint( PointF(cx, cy) );
1266
        gradientBrush.SetCenterColor( colors[numElements - 1] );
1267
        gradientBrush.SetInterpolationColors( colors, positions, numElements );
6987 jghali 1268
        m_graphics->FillPath( &gradientBrush, m_graphicsPath );
4360 cbradney 1269
 
1270
        delete[] colors;
1271
        delete[] positions;
1272
#else
1273
        int radius;
1274
        int increment;
1275
        int r1, g1, b1, a1;
1276
        int r2, g2, b2, a2;
1277
        int r3, g3, b3, a3;
1278
        double colorCoeff;
1279
        double ramp1, ramp2;
1280
        double scale1, scale2;
1281
        int clipBoxWidth, clipBoxHeight, maxDim;
8501 cbradney 1282
        Q3PtrVector<VColorStopEx> colorStops = gradient.colorStops();
4360 cbradney 1283
        VColorStopEx stop1( *colorStops[gradient.Stops() - 1] );
1284
        VColorStopEx stop2( *colorStops[gradient.Stops() - 1] );
1285
        QColor color;
1286
 
1287
        clipBoxWidth = rect.width();
1288
        clipBoxHeight = rect.height();
1289
        maxDim = sqrt( clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight ) * 2;
1290
        if ( maxDim <= 0 ) return;
1291
 
1292
        scale1 = sqrt( m_matrix.m11() * m_matrix.m11() + m_matrix.m21() * m_matrix.m21() );
1293
        scale2 = sqrt( m_matrix.m12() * m_matrix.m12() + m_matrix.m22() * m_matrix.m22() );
1294
        increment = (int) max( scale1, scale2 );
1295
        increment = (increment < 2) ? 2 : increment;
1296
 
1297
        FPoint pc( gradient.origin().x(), gradient.origin().y() );
6987 jghali 1298
        FPoint pcz( gradient.origin().x(), gradient.origin().y() );
4360 cbradney 1299
        FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
6987 jghali 1300
        FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
4360 cbradney 1301
        FPoint pv( gradient.vector().x(), gradient.vector().y() );
1302
        transformPoint( pc, pc );
1303
        transformPoint( pf, pf );
1304
        transformPoint( pv, pv );
1305
        transformPoint( pcz, pcz );
1306
        transformPoint( pfz, pfz );
1307
        double cx = pcz.x();
1308
        double cy = pcz.y();
1309
        double fx = pfz.x();
1310
        double fy = pfz.y();
1311
        double rad = sqrt( pow(pv.x() -pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
1312
 
1313
        ramp2 = stop2.rampPoint;
1314
        color =  transformColor( ScColorShade(stop2.color, stop2.shade), 1.0 );
1315
        r2 = color.red();
1316
        g2 = color.green();
1317
        b2 = color.blue();
1318
        a2 = stop2.opacity * 255;
1319
        drawCircleStrip( cx - maxDim / 2, cy - maxDim / 2, maxDim, maxDim, color.red(), color.green(), color.blue(), a2);
1320
        if ( gradient.Stops() < 2 ) return;
1321
 
1322
        for( int index = gradient.Stops() - 2; index >= 0; index--)
1323
        {
1324
                stop1 = *colorStops[index];
1325
                ramp1 = stop1.rampPoint;
4989 cbradney 1326
                color =  transformColor( ScColorShade(stop1.color, stop1.shade), 1.0 );
4360 cbradney 1327
                r1 = color.red();
1328
                g1 = color.green();
1329
                b1 = color.blue();
1330
                a1 = stop1.opacity * 255;
1331
                int radMax = rad * ramp2;
1332
                int radMin = rad * ramp1;
4989 cbradney 1333
                int r4= -1, b4= -1, g4= -1, a4= -1;
4360 cbradney 1334
                for( radius = radMax; radius > radMin; radius -= increment )
1335
                {
1336
                        colorCoeff = ( radius - radMin ) / ( (double) radMax - radMin );
1337
                        r3 = (1 - colorCoeff) * r1 + colorCoeff * r2;
1338
                        g3 = (1 - colorCoeff) * g1 + colorCoeff * g2;
1339
                        b3 = (1 - colorCoeff) * b1 + colorCoeff * b2;
1340
                        a3 = (1 - colorCoeff) * a1 + colorCoeff * a2;
4989 cbradney 1341
                        if( (r3 != r4) || (g3 != g4) || (b3 != b4) )
1342
                        {
1343
                                drawCircleStrip( cx - radius, cy - radius, radius * 2, radius * 2, r3, g3, b3, a3 );
1344
                                r4 = r3;
1345
                                g4 = g3;
1346
                                b4 = b3;
1347
                        }
4360 cbradney 1348
                }
1349
                stop2 = stop1;
1350
                ramp2 = ramp1;
1351
                r2 = r1;
1352
                g2 = g1;
1353
                b2 = b1;
1354
                a2 = a1;
1355
        }
1356
#endif
1357
}
1358
 
1359
void ScPainterEx_GDI::drawCircleStrip( int x, int y, int w, int h, int r, int g, int b, int a )
1360
{
1361
#ifndef SC_USE_GDIPLUS
6987 jghali 1362
        SaveDC( m_dc );
4360 cbradney 1363
        HPEN hPen = CreatePen( PS_NULL, 0, RGB(255,255,255));
1364
        HBRUSH hBrush = CreateSolidBrush( RGB(r, g, b));
6987 jghali 1365
        HGDIOBJ obj1 = SelectObject( m_dc, hPen );
1366
        HGDIOBJ obj2 = SelectObject( m_dc, hBrush );
1367
        Ellipse( m_dc, x, y, x + w, y + h );
1368
        SelectObject( m_dc, obj2 );
1369
        SelectObject( m_dc, obj1 );
4360 cbradney 1370
        DeleteObject( hBrush );
1371
        DeleteObject( hPen );
6987 jghali 1372
        RestoreDC( m_dc, -1 );
4360 cbradney 1373
#endif
1374
}
1375
 
1376
void ScPainterEx_GDI::getClipPathDimensions( QRect& r )
1377
{
1378
#ifdef SC_USE_GDIPLUS
1379
        Rect rect(0, 0, 0, 0);
6987 jghali 1380
        Status result = m_graphics->GetClipBounds( &rect );
4360 cbradney 1381
        if( result == Ok )
1382
        {
1383
                r.setLeft( rect.GetLeft() );
1384
                r.setRight( rect.GetRight() );
1385
                r.setBottom( rect.GetBottom() );
1386
                r.setTop( rect.GetTop() );
1387
        }
1388
#else
1389
        RECT rect = { 0, 0, 0, 0 };
6987 jghali 1390
        int result = GetClipBox( m_dc, &rect );
4360 cbradney 1391
        if( result != NULLREGION && result != ERROR )
1392
        {
1393
                r.setLeft( rect.left );
1394
                r.setRight( rect.right );
1395
                r.setBottom( rect.bottom );
1396
                r.setTop( rect.top );  
1397
        }
1398
#endif
1399
}
1400