Subversion Repositories Scribus

Rev

Rev 22725 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17263 jghali 1
 
2
/*
3
For general Scribus (>=1.3.2) copyright and licensing information please refer
4
to the COPYING file provided with the program. Following this notice may exist
5
a copyright and/or license notice that predates the release of Scribus 1.3.2
6
for which a new license (GPL+exception) is in place.
7
*/
8
/* This file is part of the KDE project.
9
   Copyright (C) 2001, 2002, 2003 The Karbon Developers
10
 
11
   This library is free software; you can redistribute it and/or
12
   modify it under the terms of the GNU Library General Public
13
   License as published by the Free Software Foundation; either
14
   version 2 of the License, or (at your option) any later version.
15
 
16
   This library is distributed in the hope that it will be useful,
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
   Library General Public License for more details.
20
 
21
   You should have received a copy of the GNU Library General Public License
22
   along with this library; see the file COPYING.LIB.  If not, write to
18122 mrdocs 23
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24
   Boston, MA 02110-1301, USA.
17263 jghali 25
*/
26
/* Adapted for Scribus 22.08.2003 by Franz Schmid */
27
// kopainter/libart wrapper
28
 
29
#include "scpainterex_ps2.h"
30
 
31
#include <cfloat>
32
#include <QPaintDevice>
33
#include <QPixmap>
34
#include <QImage>
35
 
22621 jghali 36
#include <cmath>
17263 jghali 37
#include <iostream>
38
#include <memory>
39
using namespace std;
22621 jghali 40
 
17263 jghali 41
#include "colormgmt/sccolormgmtengine.h"
42
#include "sccolorengine.h"
22621 jghali 43
#include "scimage.h"
17263 jghali 44
#include "util.h"
45
 
46
ScPs2OutputParams::ScPs2OutputParams(ScribusDoc* doc)
47
{
48
        document = doc;
49
        colorMode = ScPainterExBase::rgbMode;
50
        reloadImages = true;
51
        resolution = 72;
52
        useProfiles = false;
53
        toGray = false;
54
        mirrorH = false;
55
        mirrorV = false;
22528 craig 56
        hProfile = nullptr;
57
        rgbToOutputColorTransform = nullptr;
58
        rgbToOutputImageTransform = nullptr;
59
        cmykToOutputColorTransform = nullptr;
60
        cmykToOutputImageTransform = nullptr;
17263 jghali 61
}
62
 
22639 craig 63
ScPainterEx_Ps2::ScPainterEx_Ps2(QIODevice* iodev, QRect& rect, ScPs2OutputParams& options )
17263 jghali 64
{
65
        m_stream.setDevice( iodev );
66
        m_colorMode = options.colorMode;
67
        m_encoding  = Ascii85Encoding;
68
        m_options = options;
69
        m_width = rect.width();
70
        m_height= rect.height();
71
        m_x = rect.left();
72
        m_y = rect.top();
73
        m_fillColor = ScColorShade( QColor(0,0,0), 100 );
74
        m_strokeColor = ScColorShade( QColor(0,0,0), 100 );
75
        m_fillTrans = 1.0;
76
        m_strokeTrans = 1.0;
77
        m_fillRule = true;
78
        m_fillMode = 1;
79
        m_lineWidth = 1.0;
80
        m_offset = 0;
81
        m_array.clear();
82
        m_lineEnd = Qt::SquareCap;
83
        m_lineJoin = Qt::RoundJoin;
84
        m_fillGradient = VGradientEx(VGradientEx::linear);
85
        m_strokeGradient = VGradientEx(VGradientEx::linear);
86
        m_matrix = QTransform();
87
        m_pageTrans = QTransform();
88
        // Path state
89
        m_pathIsClosed = true;
90
        m_drawingClosedPath = false;
91
        // TODO : set proper values
92
        m_deviceDimX = 0;
93
        m_deviceDimY = 0;
94
        m_deviceResX = 0;
95
        m_deviceResY = 0;
96
        clear();
97
}
98
 
99
ScPainterEx_Ps2::~ScPainterEx_Ps2()
100
{
101
}
102
 
103
ScPainterExBase::ImageMode ScPainterEx_Ps2::imageMode()
104
{
105
        ImageMode imageMode;
106
        if (m_options.hProfile && m_options.rgbToOutputImageTransform && m_options.cmykToOutputImageTransform)
107
                imageMode = rawImages;
108
        else if (m_colorMode == cmykMode)
109
                imageMode = cmykImages;
110
        else
111
                imageMode = rgbImages;
112
        return imageMode;
113
}
114
 
115
void ScPainterEx_Ps2::transformImage( QImage* image, uchar* data, int scan)
116
{
117
        int rgb, grey;
118
        int imageWidth = image->width();
119
        int imageHeight = image->height();
120
 
121
        QRgb*  pscani;
122
        uchar *pscand;
123
 
124
        pscand = data;
125
        for ( int j = 0; j < imageHeight; j++ )
126
        {
127
                pscani = (QRgb *) image->scanLine(j);
128
                for (int i = 0; i < imageWidth; i++ )
129
                {
130
                        rgb = pscani[i];
131
                        grey = qRound(0.3 * qRed(rgb)) + qRound(0.59 * qGreen(rgb)) + qRound(0.11 * qBlue(rgb));
132
                        pscand[i] = grey;
133
                }
134
                pscand += scan;
135
        }
136
 
137
}
138
 
139
void ScPainterEx_Ps2::begin()
140
{
141
}
142
 
143
void ScPainterEx_Ps2::end()
144
{
145
 
146
}
147
 
148
void ScPainterEx_Ps2::clear()
149
{
150
 
151
}
152
 
153
void ScPainterEx_Ps2::clear( ScColorShade &c )
154
{
155
 
156
}
157
 
158
const QTransform ScPainterEx_Ps2::worldMatrix()
159
{
160
        return m_matrix;
161
}
162
 
163
void ScPainterEx_Ps2::setWorldMatrix( const QTransform &mat )
164
{
165
        m_matrix = mat;
166
}
167
 
168
void ScPainterEx_Ps2::transformPoint( const FPoint& in, FPoint& out )
169
{
170
        double x, y;
171
        x = in.x() * m_matrix.m11() + in.y() * m_matrix.m21() + m_matrix.dx();
172
        y = in.x() * m_matrix.m12() + in.y() * m_matrix.m22() + m_matrix.dy();
173
        out.setX( x );
174
        out.setY( y );
175
}
176
 
177
void ScPainterEx_Ps2::transformPoints( const FPoint* ArrayIn, FPoint* ArrayOut, uint length )
178
{
22723 jghali 179
        for (uint i = 0; i < length; i++)
17263 jghali 180
        {
181
                transformPoint( ArrayIn[i], ArrayOut[i] );
182
        }
183
}
184
 
185
void ScPainterEx_Ps2::translate( double x, double y )
186
{
187
        m_matrix.translate(x, y);
188
}
189
 
20630 jghali 190
void ScPainterEx_Ps2::translate( const QPointF& offset )
191
{
192
        m_matrix.translate(offset.x(), offset.y());
193
}
194
 
17263 jghali 195
void ScPainterEx_Ps2::rotate( double r )
196
{
197
        m_matrix.rotate(r);
198
}
199
 
200
void ScPainterEx_Ps2::scale( double x, double y )
201
{
202
        m_matrix.scale(x, y);
203
}
204
 
205
void ScPainterEx_Ps2::moveTo( const double &x, const double &y )
206
{
207
        FPoint pp( x, y );
208
        transformPoint( pp, pp );
209
        m_stream << QString("%1 %2 moveto\n").arg(pp.x()).arg(pp.y());
210
}
211
 
212
void ScPainterEx_Ps2::lineTo( const double &x, const double &y )
213
{
214
        FPoint pp( x, y );
215
        transformPoint( pp, pp );
216
        m_stream << QString("%1 %2 lineto\n").arg(pp.x()).arg(pp.y());
217
}
218
 
219
void ScPainterEx_Ps2::curveTo( FPoint p1, FPoint p2, FPoint p3 )
220
{
221
        FPoint pps[3];
222
        pps[0].setXY( p1.x(), p1.y() );
223
        pps[1].setXY( p2.x(), p2.y() );
224
        pps[2].setXY( p3.x(), p3.y() );
225
        transformPoints( pps, pps, 3 );
226
        m_stream << QString("%1 %2 %3 %4 %5 %6 curveto\n").arg(pps[0].x()).arg(pps[0].y()).arg(pps[1].x()).arg(pps[1].y()).arg(pps[2].x()).arg(pps[2].y());
227
}
228
 
229
void ScPainterEx_Ps2::newPath()
230
{
231
   m_stream << "newpath\n";
232
   //pathIsClosed = false;
233
}
234
 
235
void ScPainterEx_Ps2::closePath()
236
{
237
        m_stream << "closepath\n";
238
        m_pathIsClosed = true;
239
}
240
 
241
void ScPainterEx_Ps2::setFillRule( bool fillRule )
242
{
243
        m_fillRule = fillRule;
244
}
245
 
246
void ScPainterEx_Ps2::setFillMode( int fill )
247
{
248
        m_fillMode = fill;
249
}
250
 
251
void ScPainterEx_Ps2::setStrokeMode( int stroke )
252
{
253
        m_strokeMode = stroke;
254
}
255
 
256
void ScPainterEx_Ps2::setGradient(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew)
257
{
258
        m_fillGradient.setType(mode);
259
        m_fillGradient.setOrigin(orig);
260
        m_fillGradient.setVector(vec);
261
        m_fillGradient.setFocalPoint(foc);
262
 
263
        m_strokeGradient.setType(mode);
264
        m_strokeGradient.setOrigin(orig);
265
        m_strokeGradient.setVector(vec);
24467 jghali 266
        m_strokeGradient.setFocalPoint(foc);
17263 jghali 267
}
268
 
269
void ScPainterEx_Ps2::setPattern(ScPattern *pattern, double scaleX, double scaleY, double offsetX, double offsetY, double rotation, double skewX, double skewY, bool mirrorX, bool mirrorY)
270
{
271
        m_pattern = pattern;
272
        m_patternScaleX = scaleX / 100.0;
273
        m_patternScaleY = scaleY / 100.0;
274
        m_patternOffsetX = offsetX;
275
        m_patternOffsetY = offsetY;
276
        m_patternRotation = rotation;
277
        m_patternSkewX   = skewX;
278
        m_patternSkewY   = skewY;
279
        m_patternMirrorX = mirrorX;
280
        m_patternMirrorY = mirrorY;
281
}
282
 
283
void ScPainterEx_Ps2::fillPath()
284
{
22721 jghali 285
        if (!m_pathIsClosed)
17263 jghali 286
                closePath();
22721 jghali 287
        if (m_fillMode != 0)
17263 jghali 288
                drawVPath( 0 );
289
}
290
 
291
void ScPainterEx_Ps2::strokePath()
292
{
22721 jghali 293
        if (m_lineWidth == 0)
17263 jghali 294
                return;
295
        save();
22721 jghali 296
        if (!m_pathIsClosed)
17263 jghali 297
                closePath();
298
        drawVPath( 1 );
299
        restore();
300
}
301
 
302
ScColorShade ScPainterEx_Ps2::pen()
303
{
304
        return m_strokeColor;
305
}
306
 
307
ScColorShade ScPainterEx_Ps2::brush()
308
{
309
        return m_fillColor;
310
}
311
 
312
void ScPainterEx_Ps2::setPen( const ScColorShade &c )
313
{
314
        m_strokeColor = c;
315
}
316
 
317
void ScPainterEx_Ps2::setPen( const ScColorShade &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
318
{
319
        m_offset = 0;
320
        m_strokeColor = c;
321
        m_lineWidth = w;
322
        m_lineEnd = ca;
323
        m_lineJoin = jo;
324
        double Dt = qMax(2*w, 1.0);
325
        double Da = qMax(6*w, 1.0);
326
        m_array.clear();
327
        if (st == Qt::DashLine)
328
                m_array << Da << Dt;
329
        else if (st == Qt::DotLine)
330
                m_array << Dt;
331
        else if (st == Qt::DashDotLine)
332
                m_array << Da << Dt << Dt << Dt;
333
        else if (st == Qt::DashDotDotLine)
334
                m_array << Da << Dt << Dt << Dt << Dt << Dt;
335
}
336
 
337
void ScPainterEx_Ps2::setLineWidth( double w )
338
{
339
        m_lineWidth = w;
340
}
341
 
342
void ScPainterEx_Ps2::setPenOpacity( double op )
343
{
344
        m_strokeTrans = op;
345
}
346
 
347
void ScPainterEx_Ps2::setDash(const QVector<double>& array, double ofs)
348
{
349
        m_array = array;
350
        m_offset = ofs;
351
}
352
 
353
void ScPainterEx_Ps2::setBrush( const ScColorShade &c )
354
{
355
        m_fillColor = c;
356
}
357
 
358
void ScPainterEx_Ps2::setBrushOpacity( double op )
359
{
360
        m_fillTrans = op;
361
}
362
 
363
void ScPainterEx_Ps2::setOpacity( double op )
364
{
365
        m_fillTrans = op;
366
        m_strokeTrans = op;
367
}
368
 
369
void ScPainterEx_Ps2::setFont( const QFont &f)
370
{
371
        m_font = f;
372
}
373
 
374
QFont ScPainterEx_Ps2::font()
375
{
376
        return m_font;
377
}
378
 
379
void ScPainterEx_Ps2::save()
380
{
381
        m_stack.push( m_matrix );
382
        m_stream << "gsave\n";
383
}
384
 
385
void ScPainterEx_Ps2::restore()
386
{
387
        m_matrix = m_stack.pop();
388
        m_stream << "grestore\n";
389
}
390
 
391
void ScPainterEx_Ps2::setRasterOp( int   )
392
{
393
}
394
 
395
void ScPainterEx_Ps2::drawVPath( int mode )
396
{
397
        save();
398
        if (mode == 0)
399
        {
400
                if (m_fillMode == ScPainterExBase::Gradient)
401
                        drawGradient( m_fillGradient );
402
                else
403
                        putColor( m_fillColor, true );
404
        }
405
        else
406
        {
407
                double m11 = m_matrix.m11();
408
                double m12 = m_matrix.m12();
409
                double m21 = m_matrix.m21();
410
                double m22 = m_matrix.m22();
411
                double norm2 = m11 * m11 + m12 * m12 + m21 * m21 + m22 * m22;
412
                double penScale = sqrt(norm2 /2.0);
413
                double penWidth = (int) (m_lineWidth * penScale);
414
                m_stream << QString("%1 setlinewidth\n").arg(penWidth);
415
 
416
                m_stream << "[";
22723 jghali 417
                for (int i = 0; i < m_array.count();++ i)
17263 jghali 418
                {
419
                        m_stream << QString("%1").arg(m_array[i]) << " ";
420
                }
421
                m_stream << "]";
422
                m_stream << " 0 setdash\n";
423
 
22721 jghali 424
                if (m_lineEnd == Qt::RoundCap)
17263 jghali 425
                        m_stream << "1 setlinecap\n";
22721 jghali 426
                else if (m_lineEnd == Qt::SquareCap)
17263 jghali 427
                        m_stream << "2 setlinecap\n";
22721 jghali 428
                else if (m_lineEnd == Qt::FlatCap)
17263 jghali 429
                        m_stream << "0 setlinecap\n";
430
                else
431
                        m_stream << "0 setlinecap\n";
432
 
22721 jghali 433
                if (m_lineJoin == Qt::RoundJoin)
17263 jghali 434
                        m_stream << "1 setlinejoin\n";
22721 jghali 435
                else if (m_lineJoin == Qt::BevelJoin)
17263 jghali 436
                        m_stream << "2 setlinejoin\n";
22721 jghali 437
                else if (m_lineJoin == Qt::MiterJoin)
17263 jghali 438
                        m_stream << "0 setlinejoin\n";
439
                else
440
                        m_stream << "0 setlinejoin\n";
441
 
442
                putColor(m_strokeColor, false);
443
        }
444
        restore();
445
}
446
 
447
void ScPainterEx_Ps2::setClipPath()
448
{
449
        //TODO eoclip or clip?
450
        m_stream << "clip newpath\n";
451
        m_clipBBox = m_pathBBox;
452
}
453
 
22212 jghali 454
void ScPainterEx_Ps2::putColor(ScColorShade& colorShade, bool doFill)
17263 jghali 455
{
456
        ColorMode colorMode = m_colorMode;
22212 jghali 457
        double r = 0, g = 0, b = 0, gray = 0;
458
        double c = 0, m = 0, y = 0, k = 0;
459
        if (m_options.toGray)
17263 jghali 460
        {
22212 jghali 461
                RGBColorF rgb;
17263 jghali 462
                ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
463
                rgb.getValues(r, g, b);
22212 jghali 464
                gray = 0.3 * r + 0.59 * g + 0.11 * b;
17263 jghali 465
                if ( doFill && m_fillRule )
22212 jghali 466
                        m_stream << QString("%1 setgray eofill\n").arg(gray);
17263 jghali 467
                else if ( doFill )
22212 jghali 468
                        m_stream << QString("%1 setgray fill\n").arg(gray);
17263 jghali 469
                else
22212 jghali 470
                        m_stream << QString("%1 setgray stroke\n").arg(gray);
17263 jghali 471
                return;
472
        }
22638 craig 473
        if (m_options.hProfile && m_options.rgbToOutputColorTransform && m_options.cmykToOutputColorTransform)
17263 jghali 474
        {
475
                unsigned long colorIn[4];
476
                unsigned long colorOut[4];
22528 craig 477
                ScColorTransform cmsTranform = nullptr;
22721 jghali 478
                if (colorShade.color.getColorModel() == colorModelRGB)
17263 jghali 479
                {
22212 jghali 480
                        RGBColorF rgb;
17263 jghali 481
                        ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
22212 jghali 482
                        colorIn[0] = rgb.r * 65535.0;
483
                        colorIn[1] = rgb.g * 65535.0;
484
                        colorIn[2] = rgb.b * 65535.0;
17263 jghali 485
                        colorMode = rgbMode;
486
                        cmsTranform = m_options.rgbToOutputColorTransform;
487
                }
488
                else
489
                {
22212 jghali 490
                        CMYKColorF cmyk;
17263 jghali 491
                        ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
22212 jghali 492
                        colorIn[0] = cmyk.c * 65535.0;
493
                        colorIn[1] = cmyk.m * 65535.0;
494
                        colorIn[2] = cmyk.y * 65535.0;
495
                        colorIn[3] = cmyk.k * 65535.0;
17263 jghali 496
                        colorMode = cmykMode;
497
                        cmsTranform = m_options.cmykToOutputColorTransform;
498
                }
499
                cmsTranform.apply(colorIn, colorOut, 1 );
500
                if (m_options.hProfile.colorSpace() == ColorSpace_Rgb)
501
                {
22212 jghali 502
                        r = colorOut[0] / 65535.0;
503
                        g = colorOut[1] / 65535.0;
504
                        b = colorOut[2] / 65535.0;
17263 jghali 505
                        colorMode = rgbMode;
506
                }
507
                else if (m_options.hProfile.colorSpace() == ColorSpace_Cmyk)
508
                {
22212 jghali 509
                        c = colorOut[0] / 65535.0;
510
                        m = colorOut[1] / 65535.0;
511
                        y = colorOut[2] / 65535.0;
512
                        k = colorOut[3] / 65535.0;
17263 jghali 513
                        colorMode = cmykMode;
514
                }
515
        }
22212 jghali 516
        else if (m_colorMode == rgbMode)
17263 jghali 517
        {
22212 jghali 518
                RGBColorF rgb;
17263 jghali 519
                colorMode = rgbMode;
520
                ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
521
                rgb.getValues(r, g, b);
522
        }
523
        else if ( m_colorMode == cmykMode )
524
        {
22212 jghali 525
                CMYKColorF cmyk;
17263 jghali 526
                colorMode = cmykMode;
527
                ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
528
                cmyk.getValues(c, m, y, k);
529
        }
530
 
531
        // Finally output to file
22212 jghali 532
        if (colorMode == rgbMode)
17263 jghali 533
        {
22212 jghali 534
                if (doFill && m_fillRule)
535
                        m_stream << QString("%1 %2 %3 setrgbcolor eofill\n").arg(r).arg(g).arg(b);
17263 jghali 536
                else if ( doFill )
22212 jghali 537
                        m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r).arg(g).arg(b);
17263 jghali 538
                else
22212 jghali 539
                        m_stream << QString("%1 %2 %3 setrgbcolor stroke\n").arg(r).arg(g).arg(b);                     
17263 jghali 540
        }
541
        else if ( colorMode == cmykMode )
542
        {
22212 jghali 543
                QString colstr1 = QString("%1 %2 %3 %4 setcmykcolor").arg(c).arg(m).arg(y).arg(k);
17263 jghali 544
                if ( doFill && m_fillRule )
545
                        m_stream << colstr1 << " eofill\n";
546
                else if ( doFill )
547
                        m_stream << colstr1 << " fill\n";
548
                else
549
                        m_stream << colstr1 << " stroke\n";    
550
        }
551
}
552
 
22212 jghali 553
void ScPainterEx_Ps2::drawImage(ScImage *image, ScPainterExBase::ImageMode mode)
17263 jghali 554
{
555
        bool rgbMode = (mode == ScPainterExBase::rgbImages);
556
        bool rgbPicture = rgbMode || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceRGB);
557
        bool cmykPicture = (mode == ScPainterExBase::cmykImages || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceCMYK));
558
 
22212 jghali 559
        if (rgbPicture)
560
                drawRGBImage_ps2(image);
561
        else if (cmykPicture)
562
                drawCMYKImage_ps2(image);
17263 jghali 563
        else
22212 jghali 564
                qDebug("ScPainterEx_Ps2::drawImage() : unknown image type");
17263 jghali 565
}
566
 
22212 jghali 567
void ScPainterEx_Ps2::drawRGBImage_ps2(ScImage *image)
17263 jghali 568
{
569
        save();
570
        QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
571
        m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
572
        m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
573
        m_stream << "/DeviceRGB setcolorspace\n";
574
        if (hasAlphaChannel(image))
575
        {
576
                QImage imgTemp = image->qImage();
577
                QImage mask = imgTemp.createAlphaMask();
578
                if (m_encoding == Ascii85Encoding)
579
                {
580
                        m_stream << "currentfile /ASCII85Decode filter /ReusableStreamDecode filter\n";
581
                        writeRGBImageToStream_Ascii85(image);
582
                }
583
                else
584
                {
585
                        m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
586
                        writeRGBImageToStream_AsciiHex(image);
587
                }
588
                m_stream << "/myImage exch def\n";
589
                m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
590
                writeMaskToStream(&mask);
591
                m_stream << "/myMask exch def\n";
592
                m_stream << QString("<<\n");
593
                m_stream << QString("    /PaintType   1\n");
594
                m_stream << QString("    /PatternType 1\n");
595
                m_stream << QString("    /TilingType  3\n");
596
                m_stream << QString("    /BBox        [ 0 0 1 1 ]\n");
597
                m_stream << QString("    /XStep       2\n");
598
                m_stream << QString("    /YStep       2\n");
599
                m_stream << QString("    /PaintProc   {\n");
600
                m_stream << QString("        pop\n");
601
                m_stream << QString("        0 0 0 setrgbcolor\n");
602
                m_stream << QString("        <<\n");
603
                m_stream << QString("            /ImageType 1\n");
604
                m_stream << QString("            /Width     %1\n").arg(image->width());
605
                m_stream << QString("            /Height    %1\n").arg(image->height());
606
                m_stream << QString("            /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
607
                m_stream << QString("            /BitsPerComponent 8\n");
608
                m_stream << QString("            /Decode [0 1 0 1 0 1]\n");
609
                m_stream << QString("            /DataSource myImage\n");
610
                m_stream << QString("        >>\n");
611
                m_stream << QString("        image\n");
612
                m_stream << QString("    }\n");
613
                m_stream << QString(">> matrix makepattern setpattern\n");
614
                m_stream << QString("<<\n");
615
                m_stream << QString("    /ImageType 1\n");
616
                m_stream << QString("    /Width %1 \n").arg(image->width());
617
                m_stream << QString("    /Height %1 \n").arg(image->height());
618
                m_stream << QString("    /BitsPerComponent 1\n");
619
                m_stream << QString("    /Decode [1 0]\n");
620
                m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
621
                m_stream << QString("    /DataSource myMask\n");
622
                m_stream << QString(">>\n");
623
                m_stream << QString("imagemask\n");
624
        }
625
        else
626
        {
627
                m_stream << QString("<<\n");
628
                m_stream << QString("    /ImageType 1\n");
629
                m_stream << QString("    /Width %1\n").arg(image->width());
630
                m_stream << QString("    /Height %1\n").arg(image->height());
631
                m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
632
                m_stream << QString("    /Decode [0 1 0 1 0 1]\n");
633
                m_stream << QString("    /BitsPerComponent 8\n");
634
                //TODO case where compression is available
635
                if (m_encoding == Ascii85Encoding)
636
                {
637
                        m_stream << QString("    /DataSource currentfile /ASCII85Decode filter\n");
638
                        m_stream << QString(">>\n");
639
                        m_stream << "image\n";
640
                        writeRGBImageToStream_Ascii85(image);
641
                }
642
                else
643
                {
644
                        m_stream << QString("    /DataSource currentfile /ASCIIHexDecode filter\n");
645
                        m_stream << QString(">>\n");
646
                        m_stream << "image\n";
647
                        writeRGBImageToStream_AsciiHex(image);
648
                }
649
        }
650
        restore();
651
}
652
 
653
void ScPainterEx_Ps2::drawCMYKImage_ps2( ScImage *image )
654
{
655
        save();
656
        QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
657
        m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
658
        m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
659
        m_stream << "/DeviceCMYK setcolorspace\n";
660
        // TODO case where image have a mask
661
        bool haveMask = false;
662
        if (haveMask)
663
        {
664
 
665
        }
666
        else
667
        {
668
                m_stream << "<<\n";
669
                m_stream << QString("    /ImageType 1\n");
670
                m_stream << QString("    /Width %1\n").arg(image->width());
671
                m_stream << QString("    /Height %1\n").arg(image->height());
672
                m_stream << QString("    /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
673
                m_stream << QString("    /Decode [0 1 0 1 0 1 0 1]\n");
674
                m_stream << QString("    /BitsPerComponent 8\n");
675
                //TODO case where compression is available
676
                if (m_encoding == Ascii85Encoding)
677
                {
678
                        m_stream << QString("    /DataSource currentfile /ASCII85Decode filter\n");
679
                        m_stream << QString(">>\n");
680
                        m_stream << "image\n";
681
                        writeCMYKImageToStream_Ascii85(image);
682
                }
683
                else
684
                {
685
                        m_stream << QString("    /DataSource currentfile /ASCIIHexDecode filter\n");
686
                        m_stream << QString(">>\n");
687
                        m_stream << "image\n";
688
                        writeCMYKImageToStream_AsciiHex(image);
689
                }
690
        }
691
        restore();
692
}
693
 
694
bool ScPainterEx_Ps2::hasAlphaChannel( ScImage* image )
695
{
696
        bool   hasAlpha = false;
697
        int    width = image->width();
698
        int    height = image->height();
22723 jghali 699
        for (int y = 0; y < height; y++)
17263 jghali 700
        {
701
                QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
22723 jghali 702
                for (int x = 0; x < width; ++x)
17263 jghali 703
                {
22721 jghali 704
                        if (qAlpha(*imageBits) != 255)
17263 jghali 705
                        {
706
                                hasAlpha = true;
707
                                break;
708
                        }
709
                        imageBits++;
710
                }
711
        }
712
        return hasAlpha;
713
}
714
 
715
void ScPainterEx_Ps2::writeMaskToStream( QImage* image )
716
{
717
        int    length = 0;
718
        unsigned char bits;
719
        int    width = image->width() / 8;
720
        int    height = image->height();
721
        if ((image->width() % 8) != 0)
722
                width++;
22723 jghali 723
        for (int y = 0; y < height; ++y)
17263 jghali 724
        {
725
                unsigned char* imageBits = image->scanLine(y);
22723 jghali 726
                for (int x = 0; x < width; x++)
17263 jghali 727
                {
728
                        length++;
729
                        bits = imageBits[x];
730
                        m_stream << toHex(bits);
731
                        if ( (length % 49) == 0 )
732
                                m_stream << "\n";
733
                }
734
        }
735
        m_stream << "\n>\n";
736
}
737
 
738
void ScPainterEx_Ps2::writeRGBImageToStream_Ascii85( ScImage* image )
739
{
740
        int  cindex;
741
        int  pending = 0, written = 0;
742
        bool allZero  = true;
743
        unsigned char  four_tuple[4];
744
        const char* ascii85;
745
        quint32 value;
746
 
747
        int width = image->width();
748
        int height = image->height();
22723 jghali 749
        for (int y = 0; y < height; ++y)
17263 jghali 750
        {
751
                QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
22723 jghali 752
                for (int x = 0; x < width; ++x)
17263 jghali 753
                {
754
                        cindex = 0;
755
                        while (cindex < 3)
756
                        {
757
                                if (cindex == 0)
758
                                        four_tuple[pending++] = (uchar) qRed(*imageBits);
759
                                else if (cindex == 1)
760
                                        four_tuple[pending++] = (uchar) qGreen(*imageBits);
761
                                else if (cindex == 2)
762
                                        four_tuple[pending++] = (uchar) qBlue(*imageBits);
763
                                if (pending == 4)
764
                                {
765
                                        value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
766
                                        ascii85 = toAscii85(value, allZero);
767
                                        if (allZero)
768
                                                m_stream << "z";
769
                                        else
770
                                                m_stream << ascii85;
771
                                        written += ((allZero) ? 1 : 5);
772
                                        if (written > 75)
773
                                        {
774
                                                m_stream << "\n";
775
                                                written = 0;
776
                                        }
777
                                        pending = 0;
778
                                }
779
                                ++cindex;
780
                        }
781
 
782
                }
783
        }
784
        if (pending)
785
        {
786
                unsigned char five_tuple[6];
787
                memset (four_tuple + pending, 0, 4 - pending);
788
                value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
789
                ascii85 = toAscii85(value, allZero);
790
                memcpy (five_tuple, ascii85, 5);
791
                five_tuple[pending + 1] = 0;
792
                m_stream << (const char*) five_tuple;
793
        }
794
        m_stream << "~>\n";
795
}
796
 
797
void ScPainterEx_Ps2::writeRGBImageToStream_AsciiHex ( ScImage* image )
798
{
799
        int  length = 0;
800
        int  width = image->width();
801
        int  height = image->height();
22723 jghali 802
        for (int y = 0; y < height; ++y)
17263 jghali 803
        {
804
                QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
22723 jghali 805
                for (int x = 0; x < width; ++x)
17263 jghali 806
                {
807
                        length++;
808
                        uchar r = (uchar) qRed(*imageBits);
809
                        m_stream << toHex(r);
810
                        uchar g = (uchar) qGreen(*imageBits);
811
                        m_stream << toHex(g);
812
                        uchar b = (uchar) qBlue(*imageBits);
813
                        m_stream << toHex(b);
814
                        if ( (length % 17) == 0 )
815
                                m_stream << "\n";
816
                        imageBits++;
817
                }
818
        }
819
        m_stream << "\n>\n";
820
}
821
 
822
void ScPainterEx_Ps2::writeCMYKImageToStream_Ascii85( ScImage* image )
823
{
824
        int  written = 0;
825
        bool allZero  = true;
826
        unsigned char  four_tuple[4];
827
        const char* ascii85;
828
        quint32 value;
829
 
830
        int width = image->width();
831
        int height = image->height();
22723 jghali 832
        for (int y = 0; y < height; y++)
17263 jghali 833
        {
834
                QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
22723 jghali 835
                for (int x = 0; x < width; x++)
17263 jghali 836
                {
837
                        four_tuple[0] = (uchar) qRed(*imageBits);
838
                        four_tuple[1] = (uchar) qGreen(*imageBits);
839
                        four_tuple[2] = (uchar) qBlue(*imageBits);
840
                        four_tuple[3] = (uchar) qAlpha(*imageBits);
841
                        value   = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
842
                        ascii85 = toAscii85(value, allZero);
843
                        if (allZero)
844
                                m_stream << "z";
845
                        else
846
                                m_stream << ascii85;
847
                        written += ((allZero) ? 1 : 5);
848
                        if (written > 75)
849
                        {
850
                                m_stream << "\n";
851
                                written = 0;
852
                        }
853
                        imageBits++;
854
                }
855
        }
856
        m_stream << "~>\n";
857
}
858
 
859
void ScPainterEx_Ps2::writeCMYKImageToStream_AsciiHex( ScImage* image )
860
{
861
        int length = 0;
862
        int width = image->width();
863
        int height = image->height();
22723 jghali 864
        for (int y = 0; y < height; ++y)
17263 jghali 865
        {
866
                QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
22723 jghali 867
                for (int x = 0; x < width; ++x)
17263 jghali 868
                {
869
                        length++;
870
                        uchar c = (uchar) qRed(*imageBits);
871
                        m_stream << toHex(c);
872
                        uchar m = (uchar) qGreen(*imageBits);
873
                        m_stream << toHex(m);
874
                        uchar y = (uchar) qBlue(*imageBits);
875
                        m_stream << toHex(y);
876
                        uchar k = (uchar) qAlpha(*imageBits);
877
                        m_stream << toHex(k);
878
                        if ( (length % 13) == 0 )
879
                                m_stream << "\n";
880
                        imageBits++;
881
                }
882
        }
883
        m_stream << "\n>\n";
884
}
885
 
22090 jghali 886
void ScPainterEx_Ps2::setupPolygon(const FPointArray *points, bool closed)
17263 jghali 887
{
888
        bool nPath = true;
889
        FPoint np, np1, np2, np3;
890
        if (points->size() > 3)
891
        {
892
                newPath();
18114 jghali 893
                for (int poi=0; poi<points->size()-3; poi += 4)
17263 jghali 894
                {
18801 fschmid 895
                        if (points->isMarker(poi))
17263 jghali 896
                        {
897
                                nPath = true;
898
                                continue;
899
                        }
900
                        if (nPath)
901
                        {
902
                                np = points->point(poi);
903
                                // TODO startfigure needed?
904
                                moveTo( np.x(), np.y() );
905
                                nPath = false;
906
                        }
907
                        np = points->point(poi);
908
                        np1 = points->point(poi+1);
909
                        np2 = points->point(poi+3);
910
                        np3 = points->point(poi+2);
911
                        if ((np == np1) && (np2 == np3))
912
                                lineTo( np3.x(), np3.y() );
913
                        else
914
                                curveTo(np1, np2, np3);
915
                }
916
                if (closed)
917
                {
918
                        closePath();
919
                        m_drawingClosedPath = true;
920
                }
921
        }
922
        getPathBoundingBox( points, m_pathBBox );
923
}
924
 
925
void ScPainterEx_Ps2::drawPolygon()
926
{
927
        fillPath();
928
}
929
 
930
void ScPainterEx_Ps2::drawPolyLine()
931
{
932
        strokePath();
933
}
934
 
935
void ScPainterEx_Ps2::drawLine(FPoint start, FPoint end)
936
{
937
        newPath();
938
        moveTo(start.x(), start.y());
939
        lineTo(end.x(), end.y());
940
        strokePath();
941
}
942
 
20630 jghali 943
void ScPainterEx_Ps2::drawLine(const QPointF& start, const QPointF& end)
944
{
945
        newPath();
946
        moveTo(start.x(), start.y());
947
        lineTo(end.x(), end.y());
948
        strokePath();
949
}
950
 
17263 jghali 951
void ScPainterEx_Ps2::drawRect(double x, double y, double w, double h)
952
{
953
        newPath();
954
        moveTo( x, y );
955
        lineTo( x+w, y );
956
        lineTo( x+w, y+h );
957
        lineTo( x, y+h );
958
        lineTo( x, y );
959
        closePath();
960
        m_drawingClosedPath = true;
961
        fillPath();
962
        strokePath();
963
}
964
 
965
void ScPainterEx_Ps2::drawGradient( VGradientEx& gradient )
966
{
22289 craig 967
//      QRect clipPathRect;
17263 jghali 968
        save();
969
        //setClipPath();
970
        m_stream << "clip\n";
971
        m_clipBBox = m_pathBBox;
972
        if ( gradient.type() == VGradientEx::linear )
973
                drawLinearGradient( gradient, m_clipBBox );
974
        else if ( gradient.type() == VGradientEx::radial )
975
                drawCircularGradient( gradient, m_clipBBox );
976
        restore();
977
}
978
 
979
void ScPainterEx_Ps2::drawLinearGradient( VGradientEx& gradient, const QRect& rect )
980
{
981
        if (m_colorMode == cmykMode)
982
                drawLinearGradient_CMYK(gradient, rect);
983
        else
984
                drawLinearGradient_RGB(gradient, rect);
985
}
986
 
987
void ScPainterEx_Ps2::drawLinearGradient_RGB( VGradientEx& gradient, const QRect& rect )
988
{
22212 jghali 989
        double r1, g1, b1;
990
        double r2, g2, b2;
17263 jghali 991
        double cosa, sina;
992
        double ramp1, ramp2;
993
        double length, scale;
994
        double x1, y1, x2, y2, dx, dy;
995
        int clipBoxWidth, clipBoxHeight, maxDim;
996
        QList<VColorStopEx*> colorStops = gradient.colorStops();
997
        VColorStopEx stop1( *colorStops[0] );
998
        VColorStopEx stop2( *colorStops[0] );
22212 jghali 999
        RGBColorF rgb;
17263 jghali 1000
        FPoint p1, p2;
1001
 
22725 jghali 1002
        if (gradient.stops() < 2)
17263 jghali 1003
                return;
1004
 
1005
        clipBoxWidth = rect.width();
1006
        clipBoxHeight = rect.height();
1007
        maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
22212 jghali 1008
        if (maxDim <= 0) return;
17263 jghali 1009
 
1010
        x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
1011
        y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
1012
        x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
1013
        y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
22212 jghali 1014
        p1.setXY(x1, y1);
1015
        p2.setXY(x2, y2);
17263 jghali 1016
 
22212 jghali 1017
        dx = p2.x() - p1.x();
1018
        dy = p2.y() - p1.y();
1019
        length = sqrt(dx * dx + dy * dy);
17263 jghali 1020
        if ( length == 0.0 )
1021
                scale = 1.0;
1022
        else
1023
                scale = 1.0 / length;
1024
        cosa = dx * scale;
1025
        sina = dy * scale;
1026
 
1027
        QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
1028
        m_stream << sc.arg(cosa).arg(sina).arg(-sina).arg(cosa).arg(x1).arg(y1);
1029
 
1030
        ramp1 = stop1.rampPoint;
1031
        ScColorEngine::getShadeColorRGB(stop1.color, m_options.document, rgb, stop1.shade);
1032
        rgb.getValues(r1, g1, b1);
1033
        m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r1/255.0).arg(g1/255.0).arg(b1/255.0);
1034
 
22725 jghali 1035
        for (int index = 1; index < gradient.stops(); index++)
17263 jghali 1036
        {
1037
                stop2 = *colorStops[index];
1038
                ramp2 = stop2.rampPoint;
1039
                ScColorEngine::getShadeColorRGB(stop2.color, m_options.document, rgb, stop2.shade);
1040
                rgb.getValues(r2, g2, b2);
1041
                double xMin = length * ramp1;
1042
                double xMax = length * ramp2;
1043
 
1044
                m_stream << QString("/x1 %1 def\n").arg(xMin);
1045
                m_stream << QString("/x2 %1 def\n").arg(xMax);
22212 jghali 1046
                m_stream << QString("/r1 %1 def\n").arg(r1);
1047
                m_stream << QString("/g1 %1 def\n").arg(g1);
1048
                m_stream << QString("/b1 %1 def\n").arg(b1);
1049
                m_stream << QString("/r2 %1 def\n").arg(r2);
1050
                m_stream << QString("/g2 %1 def\n").arg(g2);
1051
                m_stream << QString("/b2 %1 def\n").arg(b2);
17263 jghali 1052
                m_stream << QString("/maxd %1 def\n").arg(maxDim);
1053
                m_stream << QString("/mmaxd %1 def\n").arg(-maxDim/2.0);
1054
                m_stream << "r1 r2 sub abs 255 mul /dr exch def\n";
1055
                m_stream << "g1 g2 sub abs 255 mul /dg exch def\n";
1056
                m_stream << "b1 b2 sub abs 255 mul /db exch def\n";
1057
                m_stream << "dr dg add db add /colsteps exch def\n";
1058
                m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
1059
                m_stream << "x2 x1 sub colsteps div /xinc exch def\n";
1060
                m_stream << "xinc 2 mul /xinc2 exch def\n";
1061
                m_stream << "x2 xinc2 lt { /xinc2 x2 def } if\n";
1062
                m_stream << "r2 r1 sub colsteps div /rinc exch def\n";
1063
                m_stream << "g2 g1 sub colsteps div /ginc exch def\n";
1064
                m_stream << "b2 b1 sub colsteps div /binc exch def\n";
1065
                //m_stream << "r1 g1 b1 setrgbcolor\n";
1066
                //m_stream << "0 mmaxd maxd maxd rectfill\n";
1067
                m_stream << "0 1 colsteps\n";
1068
                m_stream << "{\n";
1069
                m_stream << "    r1 g1 b1 setrgbcolor\n";
1070
                m_stream << "    x1 mmaxd xinc2 maxd rectfill\n"; //rectfill is a ps2 operator
1071
                m_stream << "    x1 xinc add /x1 exch def\n";
1072
                m_stream << "    r1 rinc add /r1 exch def\n";
1073
                m_stream << "    g1 ginc add /g1 exch def\n";
1074
                m_stream << "    b1 binc add /b1 exch def\n";
1075
                m_stream << "} for\n";
1076
                m_stream << "x2 mmaxd maxd maxd rectfill\n";
1077
 
1078
                stop1 = stop2;
1079
                ramp1 = ramp2;
1080
                r1 = r2;
1081
                g1 = g2;
1082
                b1 = b2;
1083
        }
1084
}
1085
 
22212 jghali 1086
void ScPainterEx_Ps2::drawLinearGradient_CMYK(VGradientEx& gradient, const QRect& rect)
17263 jghali 1087
{
22212 jghali 1088
        double c1, m1, j1, n1;
1089
        double c2, m2, j2, n2;
17263 jghali 1090
        double cosa, sina;
1091
        double ramp1, ramp2;
1092
        double length, scale;
1093
        double x1, y1, x2, y2, dx, dy;
1094
        int clipBoxWidth, clipBoxHeight, maxDim;
1095
        QList<VColorStopEx*> colorStops = gradient.colorStops();
1096
        VColorStopEx stop1( *colorStops[0] );
1097
        VColorStopEx stop2( *colorStops[0] );
22212 jghali 1098
        CMYKColorF cmyk;
17263 jghali 1099
        FPoint p1, p2;
1100
 
22725 jghali 1101
        if ( gradient.stops() < 2 )
17263 jghali 1102
                return;
1103
 
1104
        clipBoxWidth = rect.width();
1105
        clipBoxHeight = rect.height();
1106
        maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
1107
        if ( maxDim <= 0 ) return;
1108
 
1109
        x1 = m_matrix.dx() + gradient.origin().x() * m_matrix.m11();
1110
        y1 = m_matrix.dy() + gradient.origin().y() * m_matrix.m22();
1111
        x2 = m_matrix.dx() + gradient.vector().x() * m_matrix.m11();
1112
        y2 = m_matrix.dy() + gradient.vector().y() * m_matrix.m22();
1113
        p1.setXY( x1, y1 );
1114
        p2.setXY( x2, y2 );
1115
 
1116
        dx = ( p2.x() - p1.x() );
1117
        dy = ( p2.y() - p1.y() );
1118
        length = sqrt(( dx * dx + dy * dy ));
1119
        if ( length == 0.0 )
1120
                scale = 1.0;
1121
        else
1122
                scale = 1.0 / length;
1123
        cosa = dx * scale;
1124
        sina = dy * scale;
1125
 
1126
        QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
1127
        m_stream << sc.arg(cosa).arg(sina).arg(-sina).arg(cosa).arg(x1).arg(y1);
1128
 
1129
        ramp1 = stop1.rampPoint;
1130
        ScColorEngine::getShadeColorCMYK(stop1.color, m_options.document, cmyk, stop1.shade);
1131
        cmyk.getValues(c1, m1, j1, n1);
1132
        m_stream << QString("/DeviceCMYK setcolorspace\n");
22212 jghali 1133
        m_stream << QString("%1 %2 %3 %4 setcolor fill\n").arg(c1).arg(m1).arg(j1).arg(n1);
17263 jghali 1134
 
22725 jghali 1135
        for (int index = 1; index < gradient.stops(); index++)
17263 jghali 1136
        {
1137
                stop2 = *colorStops[index];
1138
                ramp2 = stop2.rampPoint;
1139
                ScColorEngine::getShadeColorCMYK(stop2.color, m_options.document, cmyk, stop2.shade);
1140
                cmyk.getValues(c2, m2, j2, n2);
1141
                double xMin = length * ramp1;
1142
                double xMax = length * ramp2;
1143
 
1144
                m_stream << QString("/x1 %1 def\n").arg(xMin);
1145
                m_stream << QString("/x2 %1 def\n").arg(xMax);
22212 jghali 1146
                m_stream << QString("/c1 %1 def\n").arg(c1);
1147
                m_stream << QString("/m1 %1 def\n").arg(m1);
1148
                m_stream << QString("/y1 %1 def\n").arg(j1);
1149
                m_stream << QString("/k1 %1 def\n").arg(n1);
1150
                m_stream << QString("/c2 %1 def\n").arg(c2);
1151
                m_stream << QString("/m2 %1 def\n").arg(m2);
1152
                m_stream << QString("/y2 %1 def\n").arg(j2);
1153
                m_stream << QString("/k2 %1 def\n").arg(n2);
17263 jghali 1154
                m_stream << QString("/maxd %1 def\n").arg(maxDim);
1155
                m_stream << QString("/mmaxd %1 def\n").arg(-maxDim/2.0);
1156
                m_stream << "c1 c2 sub abs 255 mul /dc exch def\n";
1157
                m_stream << "m1 m2 sub abs 255 mul /dm exch def\n";
1158
                m_stream << "y1 y2 sub abs 255 mul /dy exch def\n";
1159
                m_stream << "k1 k2 sub abs 255 mul /dk exch def\n";
1160
                m_stream << "dc dm add dy add dk add /colsteps exch def\n";
1161
                m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
1162
                m_stream << "x2 x1 sub colsteps div /xinc exch def\n";
1163
                m_stream << "xinc 2 mul /xinc2 exch def\n";
1164
                m_stream << "x2 xinc2 lt { /xinc2 x2 def } if\n";
1165
                m_stream << "c2 c1 sub colsteps div /cinc exch def\n";
1166
                m_stream << "m2 m1 sub colsteps div /minc exch def\n";
1167
                m_stream << "y2 y1 sub colsteps div /yinc exch def\n";
1168
                m_stream << "k2 k1 sub colsteps div /kinc exch def\n";
1169
                //m_stream << "r1 g1 b1 setrgbcolor\n";
1170
                //m_stream << "0 mmaxd maxd maxd rectfill\n";
1171
                m_stream << "0 1 colsteps\n";
1172
                m_stream << "{\n";
1173
                m_stream << "    c1 m1 y1 k1 setcolor\n";
1174
                m_stream << "    x1 mmaxd xinc2 maxd rectfill\n"; //rectfill is a ps2 operator
1175
                m_stream << "    x1 xinc add /x1 exch def\n";
1176
                m_stream << "    c1 cinc add /c1 exch def\n";
1177
                m_stream << "    m1 minc add /m1 exch def\n";
1178
                m_stream << "    y1 yinc add /y1 exch def\n";
1179
                m_stream << "    k1 kinc add /k1 exch def\n";
1180
                m_stream << "} for\n";
1181
                m_stream << "x2 mmaxd maxd maxd rectfill\n";
1182
 
1183
                stop1 = stop2;
1184
                ramp1 = ramp2;
1185
                c1 = c2;
1186
                m1 = m2;
1187
                j1 = j2;
1188
                n1 = n2;
1189
        }
1190
}
1191
 
1192
void ScPainterEx_Ps2::drawCircularGradient( VGradientEx& gradient, const QRect& rect )
1193
{
1194
        if (m_colorMode == cmykMode)
1195
                drawCircularGradient_CMYK(gradient, rect);
1196
        else
1197
                drawCircularGradient_RGB(gradient, rect);
1198
}
1199
 
1200
void ScPainterEx_Ps2::drawCircularGradient_RGB( VGradientEx& gradient, const QRect& rect )
1201
{
22212 jghali 1202
        double r1, g1, b1;
1203
        double r2, g2, b2;
17263 jghali 1204
        double ramp1, ramp2;
1205
        int clipBoxWidth, clipBoxHeight, maxDim;
1206
        QList<VColorStopEx*> colorStops = gradient.colorStops();
22725 jghali 1207
        VColorStopEx stop1( *colorStops[gradient.stops() - 1] );
1208
        VColorStopEx stop2( *colorStops[gradient.stops() - 1] );
22212 jghali 1209
        RGBColorF rgb;
17263 jghali 1210
 
1211
        clipBoxWidth = rect.width();
1212
        clipBoxHeight = rect.height();
1213
        maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
1214
        if ( maxDim <= 0 ) return;
1215
 
1216
        FPoint pc( gradient.origin().x(), gradient.origin().y() );
1217
        FPoint pcz( gradient.origin().x(), gradient.origin().y() );
1218
        FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
1219
        FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
1220
        FPoint pv( gradient.vector().x(), gradient.vector().y() );
22212 jghali 1221
        transformPoint(pc, pc);
1222
        transformPoint(pf, pf);
1223
        transformPoint(pv, pv);
1224
        transformPoint(pcz, pcz);
1225
        transformPoint(pfz, pfz);
17263 jghali 1226
        double cx = pcz.x();
1227
        double cy = pcz.y();
1228
        double rad = sqrt( pow(pv.x() -pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
1229
 
1230
        ramp2 = stop2.rampPoint;
1231
        ScColorEngine::getShadeColorRGB(stop2.color, m_options.document, rgb, stop2.shade);
1232
        rgb.getValues(r2, g2, b2);
1233
        m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r2).arg(g2).arg(b2);
22725 jghali 1234
        if ( gradient.stops() < 2 ) return;
17263 jghali 1235
 
22725 jghali 1236
        for (int index = gradient.stops() - 2; index >= 0; index--)
17263 jghali 1237
        {
1238
                stop1 = *colorStops[index];
1239
                ramp1 = stop1.rampPoint;
1240
                ScColorEngine::getShadeColorRGB(stop1.color, m_options.document, rgb, stop1.shade);
1241
                rgb.getValues(r1, g1, b1);
1242
                int radMax = qRound(rad * ramp2);
1243
                int radMin = qRound(rad * ramp1);
1244
 
1245
                m_stream << QString("/rad1 %1 def\n").arg(radMax);
1246
                m_stream << QString("/rad2 %1 def\n").arg(radMin);
1247
                m_stream << QString("/circx %1 def\n").arg(cx);
1248
                m_stream << QString("/circy %1 def\n").arg(cy);
22212 jghali 1249
                m_stream << QString("/r1 %1 def\n").arg(r1);
1250
                m_stream << QString("/g1 %1 def\n").arg(g1);
1251
                m_stream << QString("/b1 %1 def\n").arg(b1);
1252
                m_stream << QString("/r2 %1 def\n").arg(r2);
1253
                m_stream << QString("/g2 %1 def\n").arg(g2);
1254
                m_stream << QString("/b2 %1 def\n").arg(b2);
17263 jghali 1255
                m_stream << "r1 r2 sub abs 255 mul /dr exch def\n";
1256
                m_stream << "g1 g2 sub abs 255 mul /dg exch def\n";
1257
                m_stream << "b1 b2 sub abs 255 mul /db exch def\n";
1258
                m_stream << "dr dg add db add /colsteps exch def\n";
1259
                m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
1260
                m_stream << "rad2 rad1 sub colsteps div /radinc exch def\n";
1261
                m_stream << "r1 r2 sub colsteps div /rinc exch def\n";
1262
                m_stream << "g1 g2 sub colsteps div /ginc exch def\n";
1263
                m_stream << "b1 b2 sub colsteps div /binc exch def\n";
1264
                m_stream << "0 1 colsteps\n";
1265
                m_stream << "{\n";
1266
                m_stream << "    r2 g2 b2 setrgbcolor\n";
1267
                m_stream << "    circx circy rad1 0 360 arc closepath fill\n";
1268
                m_stream << "    rad1 radinc add /rad1 exch def\n";
1269
                m_stream << "    r2 rinc add /r2 exch def\n";
1270
                m_stream << "    g2 ginc add /g2 exch def\n";
1271
                m_stream << "    b2 binc add /b2 exch def\n";
1272
                m_stream << "} for\n";
1273
 
1274
                stop2 = stop1;
1275
                ramp2 = ramp1;
1276
                r2 = r1;
1277
                g2 = g1;
1278
                b2 = b1;
1279
        }
1280
}
1281
 
1282
void ScPainterEx_Ps2::drawCircularGradient_CMYK( VGradientEx& gradient, const QRect& rect )
1283
{
22212 jghali 1284
        double c1, m1, y1, k1;
1285
        double c2, m2, y2, k2;
17263 jghali 1286
        double ramp1, ramp2;
1287
        int clipBoxWidth, clipBoxHeight, maxDim;
1288
        QList<VColorStopEx*> colorStops = gradient.colorStops();
22725 jghali 1289
        VColorStopEx stop1( *colorStops[gradient.stops() - 1] );
1290
        VColorStopEx stop2( *colorStops[gradient.stops() - 1] );
22212 jghali 1291
        CMYKColorF cmyk;
17263 jghali 1292
 
1293
        clipBoxWidth = rect.width();
1294
        clipBoxHeight = rect.height();
1295
        maxDim = qRound(sqrt( (double) (clipBoxWidth * clipBoxWidth + clipBoxHeight * clipBoxHeight) )) * 2;
22212 jghali 1296
        if (maxDim <= 0) return;
17263 jghali 1297
 
1298
        FPoint pc( gradient.origin().x(), gradient.origin().y() );
1299
        FPoint pcz( gradient.origin().x(), gradient.origin().y() );
1300
        FPoint pf( gradient.focalPoint().x(), gradient.focalPoint().y() );
1301
        FPoint pfz( gradient.focalPoint().x(), gradient.focalPoint().y() );
1302
        FPoint pv( gradient.vector().x(), gradient.vector().y() );
22212 jghali 1303
        transformPoint(pc, pc);
1304
        transformPoint(pf, pf);
1305
        transformPoint(pv, pv);
1306
        transformPoint(pcz, pcz);
1307
        transformPoint(pfz, pfz);
17263 jghali 1308
        double cx = pcz.x();
1309
        double cy = pcz.y();
1310
        double rad = sqrt( pow(pv.x() -pc.x(), 2) + pow(pv.y() - pc.y(), 2) );
1311
 
1312
        ramp2 = stop2.rampPoint;
1313
        ScColorEngine::getShadeColorCMYK(stop2.color, m_options.document, cmyk, stop2.shade);
1314
        cmyk.getValues(c2, m2, y2, k2);
1315
        m_stream << QString("/DeviceCMYK setcolorspace\n");
1316
        m_stream << QString("%0 %1 %2 %3 setcolor fill\n").arg(c2).arg(m2).arg(y2).arg(k2);
22725 jghali 1317
        if (gradient.stops() < 2) return;
17263 jghali 1318
 
22725 jghali 1319
        for (int index = gradient.stops() - 2; index >= 0; index--)
17263 jghali 1320
        {
1321
                stop1 = *colorStops[index];
1322
                ramp1 = stop1.rampPoint;
1323
                ScColorEngine::getShadeColorCMYK(stop1.color, m_options.document, cmyk, stop1.shade);
1324
                cmyk.getValues(c1, m1, y1, k1);
1325
                int radMax = qRound(rad * ramp2);
1326
                int radMin = qRound(rad * ramp1);
1327
 
1328
                m_stream << QString("/rad1 %1 def\n").arg(radMax);
1329
                m_stream << QString("/rad2 %1 def\n").arg(radMin);
1330
                m_stream << QString("/circx %1 def\n").arg(cx);
1331
                m_stream << QString("/circy %1 def\n").arg(cy);
22212 jghali 1332
                m_stream << QString("/c1 %1 def\n").arg(c1);
1333
                m_stream << QString("/m1 %1 def\n").arg(m1);
1334
                m_stream << QString("/y1 %1 def\n").arg(y1);
1335
                m_stream << QString("/k1 %1 def\n").arg(k1);
1336
                m_stream << QString("/c2 %1 def\n").arg(c2);
1337
                m_stream << QString("/m2 %1 def\n").arg(m2);
1338
                m_stream << QString("/y2 %1 def\n").arg(y2);
1339
                m_stream << QString("/k2 %1 def\n").arg(k2);
17263 jghali 1340
                m_stream << "c1 c2 sub abs 255 mul /dc exch def\n";
1341
                m_stream << "m1 m2 sub abs 255 mul /dm exch def\n";
1342
                m_stream << "y1 y2 sub abs 255 mul /dy exch def\n";
1343
                m_stream << "k1 k2 sub abs 255 mul /dk exch def\n";
1344
                m_stream << "dc dm add dy add dk add /colsteps exch def\n";
1345
                m_stream << "colsteps 0.0 eq { /colsteps 1 def } if\n";
1346
                m_stream << "rad2 rad1 sub colsteps div /radinc exch def\n";
1347
                m_stream << "c1 c2 sub colsteps div /cinc exch def\n";
1348
                m_stream << "m1 m2 sub colsteps div /minc exch def\n";
1349
                m_stream << "y1 y2 sub colsteps div /yinc exch def\n";
1350
                m_stream << "k1 k2 sub colsteps div /kinc exch def\n";
1351
                m_stream << "0 1 colsteps\n";
1352
                m_stream << "{\n";
1353
                m_stream << "    c2 m2 y2 k2 setcolor\n";
1354
                m_stream << "    circx circy rad1 0 360 arc closepath fill\n";
1355
                m_stream << "    rad1 radinc add /rad1 exch def\n";
1356
                m_stream << "    c2 cinc add /c2 exch def\n";
1357
                m_stream << "    m2 minc add /m2 exch def\n";
1358
                m_stream << "    y2 yinc add /y2 exch def\n";
1359
                m_stream << "    k2 kinc add /k2 exch def\n";
1360
                m_stream << "} for\n";
1361
 
1362
                stop2 = stop1;
1363
                ramp2 = ramp1;
1364
                c2 = c1;
1365
                m2 = m1;
1366
                y2 = y1;
1367
                k2 = k1;
1368
        }
1369
}
1370
 
22090 jghali 1371
void ScPainterEx_Ps2::getPathBoundingBox(const FPointArray* points, QRect& r )
17263 jghali 1372
{
1373
        FPoint point;
1374
        double bottom = DBL_MAX, top   = DBL_MIN;
1375
        double left   = DBL_MAX, right = DBL_MIN;
1376
 
1377
        r.setCoords(0, 0, 0, 0);
1378
 
18114 jghali 1379
        for (int i = 0; i < points->size(); i++ )
17263 jghali 1380
        {
1381
                point = points->point(i);
22721 jghali 1382
                if (points->isMarker(i))
17263 jghali 1383
                        continue;
1384
                transformPoint(point, point);
22721 jghali 1385
                if (point.x() < left) left = point.x();
1386
                if (point.x() > right) right = point.x();
1387
                if (point.y() < bottom) bottom = point.y();
1388
                if (point.y() > top) top = point.y();
17263 jghali 1389
        }
1390
        r.setCoords( qRound(left), qRound(bottom), qRound(right), qRound(top) );
1391
}
1392