Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
6125 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
*/
7
/***************************************************************************
8
                          util.cpp  -  description
9
                             -------------------
10
    begin                : Fri Sep 14 2001
11
    copyright            : (C) 2001 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
 ***************************************************************************/
14
 
15
/***************************************************************************
16
 *                                                                         *
17
 *   This program is free software; you can redistribute it and/or modify  *
18
 *   it under the terms of the GNU General Public License as published by  *
19
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 *   (at your option) any later version.                                   *
21
 *                                                                         *
22
 ***************************************************************************/
23
 
24
#include "colorutil.h"
25
 
26
#include <qbitmap.h>
27
#include <qdatetime.h> 
28
#include <qpainter.h>
29
#include <qcheckbox.h>
30
// #include <algorithm>
31
// #include <cstdlib>
32
// #include <cmath>
33
 
34
#include "scconfig.h"
35
 
36
//#ifdef HAVE_UNISTD_H
37
//#include <unistd.h>
38
//#endif
39
 
40
#if defined(_WIN32)
41
#if defined(_MSC_VER)
42
#define __STDC__ 1 // hack to get md5_buffer correctly identified
43
#endif
44
#include <valarray>
45
#include <windows.h>
46
#endif
47
 
48
#include "md5.h"
49
 
50
// #include <setjmp.h>
51
// #include "commonstrings.h"
52
// #include "pagestructs.h"
53
// #include "prefsfile.h"
54
// #include "prefscontext.h"
55
// #include "prefstable.h"
56
// #include "prefsmanager.h"
57
// #include "qprocess.h"
58
// #include "scmessagebox.h"
59
#include "scribusdoc.h"
60
#include "scpixmapcache.h"
61
// #include "scpaths.h"
62
// #include "text/nlsconfig.h"
63
#include "util.h"
64
 
65
extern "C"
66
{
67
#define XMD_H           // shut JPEGlib up
68
#if defined(Q_OS_UNIXWARE)
69
#  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
70
#endif
71
#include <jpeglib.h>
72
#include <jerror.h>
73
#undef HAVE_STDLIB_H
74
#ifdef const
75
#  undef const          // remove crazy C hackery in jconfig.h
76
#endif
77
}
78
 
79
/*#include "scribus.h"
80
#include <ft2build.h>
81
#include FT_FREETYPE_H
82
#include FT_OUTLINE_H
83
#include FT_GLYPH_H
84
#ifdef HAVE_LIBZ
85
        #include <zlib.h>
86
#endif
87
#ifdef HAVE_TIFF
88
        #include <tiffio.h>
89
#endif*/
90
#ifdef HAVE_CMS
91
        #include CMS_INC
92
#endif
93
 
94
 
95
using namespace std;
96
 
97
 
98
QImage ProofImage(QImage *Image, ScribusDoc* doc)
99
{
100
#ifdef HAVE_CMS
101
        QImage out = Image->copy();
102
        bool cmsUse = doc ? doc->HasCMS : false;
103
        bool softProofing = doc ? doc->SoftProofing : false;
104
        if (cmsUse && softProofing)
105
        {
106
                int outheight=out.height();
107
                for (int i=0; i < outheight; ++i)
108
                {
109
                        LPBYTE ptr = out.scanLine(i);
110
                        cmsDoTransform(doc->stdProofImg, ptr, ptr, out.width());
111
                }
112
        }
113
        else
114
        {
115
                if (cmsUse)
116
                {
117
                        int outheight=out.height();
118
                        for (int i=0; i < outheight; ++i)
119
                        {
120
                                LPBYTE ptr = out.scanLine(i);
121
                                cmsDoTransform(doc->stdTransImg, ptr, ptr, out.width());
122
                        }
123
                }
124
        }
125
        return out;
126
#else
127
        return Image->copy();
128
#endif
129
}
130
 
131
QColor SetColor(ScribusDoc *currentDoc, QString color, int shad)
132
{
133
        return currentDoc->PageColors[color].getShadeColorProof(shad);
134
}
135
 
136
 
137
/**
138
 * QPixmaps are really slow with Qt/Mac 3.3.4. Really, *really*, slow.
139
 * So we better cache them.
140
 */
141
QPixmap * getSmallPixmap(QColor rgb)
142
{
143
        static ScPixmapCache<QRgb> pxCache;
144
 
145
        QRgb index=rgb.rgb();
146
        if (pxCache.contains(index))
147
                return pxCache[index];
148
 
149
        QPixmap *pm = new QPixmap(15, 15);
150
        pm->fill(rgb);
151
        QPainter p;
152
        p.begin(pm);
153
        p.setBrush(Qt::NoBrush);
154
        QPen b(Qt::black, 1);
155
        p.setPen(b);
156
        p.drawRect(0, 0, 15, 15);
157
        p.end();
158
        pxCache.insert(index, pm);
159
        return pm;
160
}
161
 
162
QPixmap * getWidePixmap(QColor rgb)
163
{
164
        static ScPixmapCache<QRgb> pxCache;
165
 
166
        QRgb index=rgb.rgb();
167
        if (pxCache.contains(index))
168
                return pxCache[index];
169
 
170
        QPixmap *pm = new QPixmap(30, 15);
171
        pm->fill(rgb);
172
        pxCache.insert(index, pm);
173
        return pm;
174
}
175
 
176
static Q_UINT64 code64(ScColor & col) {
177
        int C, M, Y, K, R, G, B;
178
        Q_UINT64 result=0;
179
        col.getRGB( &R, &G, &B );
180
        col.getCMYK( &C, &M, &Y, &K );
181
        result |= col.getColorModel() == colorModelRGB ? 1 : 0;
182
        result |= col.isOutOfGamut() ? 64 : 0;
183
        result |= col.isSpotColor() ? 32 : 0;
184
        result |= col.isRegistrationColor() ? 16 : 0;
185
        result <<= 8;
186
        result |= C;
187
        result <<= 8;
188
        result |= M;
189
        result <<= 8;
190
        result |= Y;
191
        result <<= 8;
192
        result |= K;
193
        result <<= 8;
194
        result |= R;
195
        result <<= 8;
196
        result |= G;
197
        result <<= 8;
198
        result |= B;
199
        return result;
200
}
201
 
202
QPixmap * getFancyPixmap(ScColor col) {
203
        static ScPixmapCache<Q_UINT64> pxCache;
204
 
205
        static QPixmap alertIcon;
206
        static QPixmap cmykIcon;
207
        static QPixmap rgbIcon;
208
        static QPixmap spotIcon;
209
        static QPixmap regIcon;
210
        static bool iconsInitialized = false;
211
 
212
        if ( !iconsInitialized ) {
213
                alertIcon = loadIcon("alert.png");
214
                cmykIcon = loadIcon("cmyk.png");
215
                rgbIcon = loadIcon("rgb.png");
216
                spotIcon = loadIcon("spot.png");
217
                regIcon = loadIcon("register.png");
218
                iconsInitialized = true;
219
        }
220
 
221
        Q_UINT64 res=code64(col);
222
        if (pxCache.contains(res))
223
                return pxCache[res];
224
 
225
        QPixmap *pa=new QPixmap(60, 15);
226
        QPixmap *pm=getSmallPixmap(col.getRawRGBColor());
227
        pa->fill(Qt::white);
228
        paintAlert(*pm, *pa, 0, 0);
229
        col.checkGamut();
230
        if (col.isOutOfGamut())
231
                paintAlert(alertIcon, *pa, 15, 0);
232
        if ((col.getColorModel() == colorModelCMYK) || (col.isSpotColor()))
233
                paintAlert(cmykIcon, *pa, 30, 0);
234
        else
235
                paintAlert(rgbIcon, *pa, 30, 0);
236
        if (col.isSpotColor())
237
                paintAlert(spotIcon, *pa, 46, 2);
238
        if (col.isRegistrationColor())
239
                paintAlert(regIcon, *pa, 45, 0);
240
        pxCache.insert(res, pa);
241
        return pa;
242
}
243
 
244
 
245
void paintAlert(QPixmap &toPaint, QPixmap &target, int x, int y, bool useMask)
246
{
247
        // there is no alpha mask in the beginning
248
        if (useMask)
249
        {
250
                if (target.mask()==0)
251
                        target.setMask(QBitmap(target.width(), target.height(), useMask));
252
        }
253
        QPainter p;
254
        p.begin(&target);
255
        p.drawPixmap(x, y, toPaint);
256
        if (useMask)
257
        {
258
                QPainter alpha; // transparency handling
259
                alpha.begin(target.mask());
260
                alpha.setBrush(Qt::color1);
261
                alpha.setPen(Qt::color1);
262
                alpha.drawRect(x, y, 15, 15);
263
                alpha.end();
264
        }
265
        p.end();
266
}
267
 
268
unsigned char INT_MULT ( unsigned char a, unsigned char b )
269
{
270
        int c = a * b + 0x80;
271
        return (unsigned char)(( ( c >> 8 ) + c ) >> 8);
272
}
273
 
274
void RGBTOHSV ( uchar& red, uchar& green, uchar& blue )
275
{
276
        int r, g, b;
277
        double h, s, v;
278
        int min, max;
279
        h = 0.;
280
        r = red;
281
        g = green;
282
        b = blue;
283
        if ( r > g )
284
        {
285
                max = QMAX( r, b );
286
                min = QMIN( g, b );
287
        }
288
        else
289
        {
290
                max = QMAX( g, b );
291
                min = QMIN( r, b );
292
        }
293
        v = max;
294
        if ( max != 0 )
295
                s = ( ( max - min ) * 255 ) / (double)max;
296
        else
297
                s = 0;
298
        if ( s == 0 )
299
                h = 0;
300
        else
301
        {
302
                int delta = max - min;
303
                if ( r == max )
304
                        h = ( g - b ) / (double)delta;
305
                else if ( g == max )
306
                        h = 2 + ( b - r ) / (double)delta;
307
                else if ( b == max )
308
                        h = 4 + ( r - g ) / (double)delta;
309
                h *= 42.5;
310
                if ( h < 0 )
311
                        h += 255;
312
                if ( h > 255 )
313
                        h -= 255;
314
        }
315
        red   = (uchar)h;
316
        green = (uchar)s;
317
        blue  = (uchar)v;
318
}
319
 
320
void HSVTORGB ( uchar& hue, uchar& saturation, uchar& value )
321
{
322
        if ( saturation == 0 )
323
        {
324
                hue        = value;
325
                saturation = value;
326
                value      = value;
327
        }
328
        else
329
        {
330
                double h = hue * 6. / 255.;
331
                double s = saturation / 255.;
332
                double v = value / 255.;
333
 
334
                double f = h - (int)h;
335
                double p = v * ( 1. - s );
336
                double q = v * ( 1. - ( s * f ) );
337
                double t = v * ( 1. - ( s * ( 1. - f ) ) );
338
                // Worth a note here that gcc 2.96 will generate different results
339
                // depending on optimization mode on i386.
340
                switch ((int)h)
341
                {
342
                case 0:
343
                        hue        = (uchar)( v * 255 );
344
                        saturation = (uchar)( t * 255 );
345
                        value      = (uchar)( p * 255 );
346
                        break;
347
                case 1:
348
                        hue        = (uchar)( q * 255 );
349
                        saturation = (uchar)( v * 255 );
350
                        value      = (uchar)( p * 255 );
351
                        break;
352
                case 2:
353
                        hue        = (uchar)( p * 255 );
354
                        saturation = (uchar)( v * 255 );
355
                        value      = (uchar)( t * 255 );
356
                        break;
357
                case 3:
358
                        hue        = (uchar)( p * 255 );
359
                        saturation = (uchar)( q * 255 );
360
                        value      = (uchar)( v * 255 );
361
                        break;
362
                case 4:
363
                        hue        = (uchar)( t * 255 );
364
                        saturation = (uchar)( p * 255 );
365
                        value      = (uchar)( v * 255 );
366
                        break;
367
                case 5:
368
                        hue        = (uchar)( v * 255 );
369
                        saturation = (uchar)( p * 255 );
370
                        value      = (uchar)( q * 255 );
371
                }
372
        }
373
}
374
 
375
void RGBTOHLS ( uchar& red, uchar& green, uchar& blue )
376
{
377
        int r = red;
378
        int g = green;
379
        int b = blue;
380
        int min, max;
381
        if ( r > g )
382
        {
383
                max = QMAX( r, b );
384
                min = QMIN( g, b );
385
        }
386
        else
387
        {
388
                max = QMAX( g, b );
389
                min = QMIN( r, b );
390
        }
391
        double h;
392
        double l = ( max + min ) / 2.;
393
        double s;
394
        if ( max == min )
395
        {
396
                s = 0.;
397
                h = 0.;
398
        }
399
        else
400
        {
401
                int delta = max - min;
402
                if ( l < 128 )
403
                        s = 255 * (double)delta / (double)( max + min );
404
                else
405
                        s = 255 * (double)delta / (double)( 511 - max - min );
406
                if ( r == max )
407
                        h = ( g - b ) / (double)delta;
408
                else if ( g == max )
409
                        h = 2 + ( b - r ) / (double)delta;
410
                else
411
                        h = 4 + ( r - g ) / (double)delta;
412
                h *= 42.5;
413
                if ( h < 0 )
414
                        h += 255;
415
                else if ( h > 255 )
416
                        h -= 255;
417
        }
418
        red   = (uchar)h;
419
        green = (uchar)l;
420
        blue  = (uchar)s;
421
}
422
 
423
int HLSVALUE ( double n1, double n2, double hue )
424
{
425
        double value;
426
        if ( hue > 255 )
427
                hue -= 255;
428
        else if ( hue < 0 )
429
                hue += 255;
430
        if ( hue < 42.5 )
431
                value = n1 + ( n2 - n1 ) * ( hue / 42.5 );
432
        else if ( hue < 127.5 )
433
                value = n2;
434
        else if ( hue < 170 )
435
                value = n1 + ( n2 - n1 ) * ( ( 170 - hue ) / 42.5 );
436
        else
437
                value = n1;
438
        return (int)( value * 255 );
439
}
440
 
441
void HLSTORGB ( uchar& hue, uchar& lightness, uchar& saturation )
442
{
443
        double h = hue;
444
        double l = lightness;
445
        double s = saturation;
446
        if ( s == 0 )
447
        {
448
                hue        = (uchar)l;
449
                lightness  = (uchar)l;
450
                saturation = (uchar)l;
451
        }
452
        else
453
        {
454
                double m1, m2;
455
                if ( l < 128 )
456
                        m2 = ( l * ( 255 + s ) ) / 65025.;
457
                else
458
                        m2 = ( l + s - ( l * s ) / 255. ) / 255.;
459
                m1 = ( l / 127.5 ) - m2;
460
                hue        = HLSVALUE( m1, m2, h + 85 );
461
                lightness  = HLSVALUE( m1, m2, h );
462
                saturation = HLSVALUE( m1, m2, h - 85 );
463
        }
464
}
465
 
6193 fschmid 466
double getCurveYValue(FPointArray &curve, double x, bool linear)
6125 cbradney 467
{
468
    double t;
469
    FPoint p;
470
    FPoint p0,p1,p2,p3;
471
    double c0,c1,c2,c3;
472
    double val = 0.5;
473
    if(curve.size() == 0)
474
        return 0.5;
475
    // First find curve segment
476
    p = curve.point(0);
477
    if(x < p.x())
478
        return p.y();
479
    p = curve.point(curve.size()-1);
480
    if(x >= p.x())
481
        return p.y();
482
        uint cc = 0;
483
    // Find the four control points (two on each side of x)    
484
    p = curve.point(0);
485
    while(x >= p.x())
486
    {
487
                cc++;
488
        p = curve.point(cc);
489
    }
490
    if (cc > 1)
491
    {
492
        p0 = curve.point(cc-2);
493
        p1 = curve.point(cc-1);
494
    }
495
    else
496
        p1 = p0 = curve.point(0);
497
    p2 = p;
498
    if (cc < curve.size()-1)
499
        p3 = curve.point(cc+1);
500
    else
501
        p3 = p;
502
    // Calculate the value
6193 fschmid 503
        if (linear)
504
        {
505
                double mc;
506
                if (p1.x() - p2.x() != 0.0)
507
                        mc = (p1.y() - p2.y()) / (p1.x() - p2.x());
508
                else
509
                        mc = p2.y() / p2.x();
510
                val = (x - p1.x()) * mc + p1.y();
511
        }
512
        else
513
        {
514
                t = (x - p1.x()) / (p2.x() - p1.x());
515
                c2 = (p2.y() - p0.y()) * (p2.x()-p1.x()) / (p2.x()-p0.x());
516
                c3 = p1.y();
517
                c0 = -2*p2.y() + 2*c3 + c2 + (p3.y() - p1.y()) * (p2.x() - p1.x()) / (p3.x() - p1.x());
518
                c1 = p2.y() - c3 - c2 - c0;
519
                val = ((c0*t + c1)*t + c2)*t + c3;
520
        }
521
        if(val < 0.0)
522
                val = 0.0;
523
        if(val > 1.0)
524
                val = 1.0;
525
        return val;
6125 cbradney 526
}
527