~ubuntu-branches/ubuntu/saucy/goldencheetah/saucy

« back to all changes in this revision

Viewing changes to qwt/src/qwt_color_map.cpp

  • Committer: Package Import Robot
  • Author(s): KURASHIKI Satoru
  • Date: 2013-08-18 07:02:45 UTC
  • mfrom: (4.1.8 sid)
  • Revision ID: package-import@ubuntu.com-20130818070245-zgdvb47e1k3mtgil
Tags: 3.0-3
debian/control: remove needless dependency. (Closes: #719571)

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 * modify it under the terms of the Qwt License, Version 1.0
8
8
 *****************************************************************************/
9
9
 
10
 
#include "qwt_array.h"
 
10
#include "qwt_color_map.h"
11
11
#include "qwt_math.h"
12
 
#include "qwt_double_interval.h"
13
 
#include "qwt_color_map.h"
14
 
 
15
 
#if QT_VERSION < 0x040000
16
 
#include <qvaluelist.h>
17
 
typedef QValueVector<QRgb> QwtColorTable;
18
 
#else
19
 
typedef QVector<QRgb> QwtColorTable;
20
 
#endif
 
12
#include "qwt_interval.h"
 
13
#include <qnumeric.h>
21
14
 
22
15
class QwtLinearColorMap::ColorStops
23
16
{
24
17
public:
25
18
    ColorStops()
26
19
    {
27
 
#if QT_VERSION >= 0x040000
28
 
        _stops.reserve(256);
29
 
#endif
 
20
        _stops.reserve( 256 );
30
21
    }
31
22
 
32
 
    void insert(double pos, const QColor &color);
33
 
    QRgb rgb(QwtLinearColorMap::Mode, double pos) const;
 
23
    void insert( double pos, const QColor &color );
 
24
    QRgb rgb( QwtLinearColorMap::Mode, double pos ) const;
34
25
 
35
 
    QwtArray<double> stops() const;
 
26
    QVector<double> stops() const;
36
27
 
37
28
private:
38
29
 
40
31
    {
41
32
    public:
42
33
        ColorStop():
43
 
            pos(0.0),
44
 
            rgb(0)
 
34
            pos( 0.0 ),
 
35
            rgb( 0 )
45
36
        {
46
37
        };
47
38
 
48
 
        ColorStop(double p, const QColor &c):
49
 
            pos(p),
50
 
            rgb(c.rgb())
 
39
        ColorStop( double p, const QColor &c ):
 
40
            pos( p ),
 
41
            rgb( c.rgb() )
51
42
        {
52
 
            r = qRed(rgb);
53
 
            g = qGreen(rgb);
54
 
            b = qBlue(rgb);
 
43
            r = qRed( rgb );
 
44
            g = qGreen( rgb );
 
45
            b = qBlue( rgb );
55
46
        }
56
47
 
57
48
        double pos;
59
50
        int r, g, b;
60
51
    };
61
52
 
62
 
    inline int findUpper(double pos) const; 
63
 
    QwtArray<ColorStop> _stops;
 
53
    inline int findUpper( double pos ) const;
 
54
    QVector<ColorStop> _stops;
64
55
};
65
56
 
66
 
void QwtLinearColorMap::ColorStops::insert(double pos, const QColor &color)
 
57
void QwtLinearColorMap::ColorStops::insert( double pos, const QColor &color )
67
58
{
68
59
    // Lookups need to be very fast, insertions are not so important.
69
60
    // Anyway, a balanced tree is what we need here. TODO ...
75
66
    if ( _stops.size() == 0 )
76
67
    {
77
68
        index = 0;
78
 
#if QT_VERSION < 0x040000
79
 
        _stops.resize(1, QGArray::SpeedOptim);
80
 
#else
81
 
        _stops.resize(1);
82
 
#endif
 
69
        _stops.resize( 1 );
83
70
    }
84
71
    else
85
72
    {
86
 
        index = findUpper(pos);
87
 
        if ( index == (int)_stops.size() || 
88
 
            qwtAbs(_stops[index].pos - pos) >= 0.001 )
 
73
        index = findUpper( pos );
 
74
        if ( index == _stops.size() ||
 
75
                qAbs( _stops[index].pos - pos ) >= 0.001 )
89
76
        {
90
 
#if QT_VERSION < 0x040000
91
 
            _stops.resize(_stops.size() + 1, QGArray::SpeedOptim);
92
 
#else
93
 
            _stops.resize(_stops.size() + 1);
94
 
#endif
 
77
            _stops.resize( _stops.size() + 1 );
95
78
            for ( int i = _stops.size() - 1; i > index; i-- )
96
79
                _stops[i] = _stops[i-1];
97
80
        }
98
81
    }
99
82
 
100
 
    _stops[index] = ColorStop(pos, color);
 
83
    _stops[index] = ColorStop( pos, color );
101
84
}
102
85
 
103
 
inline QwtArray<double> QwtLinearColorMap::ColorStops::stops() const
 
86
inline QVector<double> QwtLinearColorMap::ColorStops::stops() const
104
87
{
105
 
    QwtArray<double> positions(_stops.size());
106
 
    for ( int i = 0; i < (int)_stops.size(); i++ )
 
88
    QVector<double> positions( _stops.size() );
 
89
    for ( int i = 0; i < _stops.size(); i++ )
107
90
        positions[i] = _stops[i].pos;
108
91
    return positions;
109
92
}
110
93
 
111
 
inline int QwtLinearColorMap::ColorStops::findUpper(double pos) const
 
94
inline int QwtLinearColorMap::ColorStops::findUpper( double pos ) const
112
95
{
113
96
    int index = 0;
114
97
    int n = _stops.size();
115
98
 
116
99
    const ColorStop *stops = _stops.data();
117
 
    
118
 
    while (n > 0) 
 
100
 
 
101
    while ( n > 0 )
119
102
    {
120
103
        const int half = n >> 1;
121
104
        const int middle = index + half;
122
105
 
123
 
        if ( stops[middle].pos <= pos ) 
 
106
        if ( stops[middle].pos <= pos )
124
107
        {
125
108
            index = middle + 1;
126
109
            n -= half + 1;
127
 
        } 
128
 
        else 
 
110
        }
 
111
        else
129
112
            n = half;
130
113
    }
131
114
 
133
116
}
134
117
 
135
118
inline QRgb QwtLinearColorMap::ColorStops::rgb(
136
 
    QwtLinearColorMap::Mode mode, double pos) const
 
119
    QwtLinearColorMap::Mode mode, double pos ) const
137
120
{
138
121
    if ( pos <= 0.0 )
139
122
        return _stops[0].rgb;
140
123
    if ( pos >= 1.0 )
141
 
        return _stops[(int)(_stops.size() - 1)].rgb;
 
124
        return _stops[ _stops.size() - 1 ].rgb;
142
125
 
143
 
    const int index = findUpper(pos);
 
126
    const int index = findUpper( pos );
144
127
    if ( mode == FixedColors )
145
128
    {
146
129
        return _stops[index-1].rgb;
150
133
        const ColorStop &s1 = _stops[index-1];
151
134
        const ColorStop &s2 = _stops[index];
152
135
 
153
 
        const double ratio = (pos - s1.pos) / (s2.pos - s1.pos);
154
 
 
155
 
        const int r = s1.r + qRound(ratio * (s2.r - s1.r));
156
 
        const int g = s1.g + qRound(ratio * (s2.g - s1.g));
157
 
        const int b = s1.b + qRound(ratio * (s2.b - s1.b));
158
 
    
159
 
        return qRgb(r, g, b);
 
136
        const double ratio = ( pos - s1.pos ) / ( s2.pos - s1.pos );
 
137
 
 
138
        const int r = s1.r + qRound( ratio * ( s2.r - s1.r ) );
 
139
        const int g = s1.g + qRound( ratio * ( s2.g - s1.g ) );
 
140
        const int b = s1.b + qRound( ratio * ( s2.b - s1.b ) );
 
141
 
 
142
        return qRgb( r, g, b );
160
143
    }
161
144
}
162
145
 
163
146
//! Constructor
164
 
QwtColorMap::QwtColorMap(Format format):
165
 
    d_format(format)
 
147
QwtColorMap::QwtColorMap( Format format ):
 
148
    d_format( format )
166
149
{
167
150
}
168
151
 
175
158
   Build and return a color map of 256 colors
176
159
 
177
160
   The color table is needed for rendering indexed images in combination
178
 
   with using colorIndex(). 
 
161
   with using colorIndex().
179
162
 
180
163
   \param interval Range for the values
181
164
   \return A color table, that can be used for a QImage
182
165
*/
183
 
QwtColorTable QwtColorMap::colorTable(
184
 
    const QwtDoubleInterval &interval) const
 
166
QVector<QRgb> QwtColorMap::colorTable( const QwtInterval &interval ) const
185
167
{
186
 
    QwtColorTable table(256);
 
168
    QVector<QRgb> table( 256 );
187
169
 
188
170
    if ( interval.isValid() )
189
171
    {
190
 
        const double step = interval.width() / (table.size() - 1);
191
 
        for ( int i = 0; i < (int) table.size(); i++ )
192
 
            table[i] = rgb(interval, interval.minValue() + step * i);
 
172
        const double step = interval.width() / ( table.size() - 1 );
 
173
        for ( int i = 0; i < table.size(); i++ )
 
174
            table[i] = rgb( interval, interval.minValue() + step * i );
193
175
    }
194
176
 
195
177
    return table;
202
184
    QwtLinearColorMap::Mode mode;
203
185
};
204
186
 
205
 
/*! 
 
187
/*!
206
188
   Build a color map with two stops at 0.0 and 1.0. The color
207
189
   at 0.0 is Qt::blue, at 1.0 it is Qt::yellow.
208
190
 
209
191
   \param format Preferred format of the color map
210
192
*/
211
 
QwtLinearColorMap::QwtLinearColorMap(QwtColorMap::Format format):
212
 
    QwtColorMap(format)
 
193
QwtLinearColorMap::QwtLinearColorMap( QwtColorMap::Format format ):
 
194
    QwtColorMap( format )
213
195
{
214
196
    d_data = new PrivateData;
215
197
    d_data->mode = ScaledColors;
216
198
 
217
 
    setColorInterval( Qt::blue, Qt::yellow);
218
 
}
219
 
 
220
 
//! Copy constructor
221
 
QwtLinearColorMap::QwtLinearColorMap(const QwtLinearColorMap &other):
222
 
    QwtColorMap(other)
223
 
{
224
 
    d_data = new PrivateData;
225
 
    *this = other;
 
199
    setColorInterval( Qt::blue, Qt::yellow );
226
200
}
227
201
 
228
202
/*!
229
 
   Build a color map with two stops at 0.0 and 1.0. 
 
203
   Build a color map with two stops at 0.0 and 1.0.
230
204
 
231
205
   \param color1 Color used for the minimum value of the value interval
232
206
   \param color2 Color used for the maximum value of the value interval
233
207
   \param format Preferred format of the coor map
234
208
*/
235
 
QwtLinearColorMap::QwtLinearColorMap(const QColor &color1, 
236
 
        const QColor &color2, QwtColorMap::Format format):
237
 
    QwtColorMap(format)
 
209
QwtLinearColorMap::QwtLinearColorMap( const QColor &color1,
 
210
        const QColor &color2, QwtColorMap::Format format ):
 
211
    QwtColorMap( format )
238
212
{
239
213
    d_data = new PrivateData;
240
214
    d_data->mode = ScaledColors;
241
 
    setColorInterval(color1, color2); 
 
215
    setColorInterval( color1, color2 );
242
216
}
243
217
 
244
218
//! Destructor
247
221
    delete d_data;
248
222
}
249
223
 
250
 
//! Assignment operator
251
 
QwtLinearColorMap &QwtLinearColorMap::operator=(
252
 
    const QwtLinearColorMap &other)
253
 
{
254
 
    QwtColorMap::operator=(other);
255
 
    *d_data = *other.d_data;
256
 
    return *this;
257
 
}
258
 
 
259
 
//! Clone the color map
260
 
QwtColorMap *QwtLinearColorMap::copy() const
261
 
{
262
 
    QwtLinearColorMap* map = new QwtLinearColorMap();
263
 
    *map = *this;
264
 
 
265
 
    return map;
266
 
}
267
 
 
268
224
/*!
269
225
   \brief Set the mode of the color map
270
226
 
271
227
   FixedColors means the color is calculated from the next lower
272
228
   color stop. ScaledColors means the color is calculated
273
 
   by interpolating the colors of the adjacent stops. 
 
229
   by interpolating the colors of the adjacent stops.
274
230
 
275
231
   \sa mode()
276
232
*/
277
 
void QwtLinearColorMap::setMode(Mode mode)
 
233
void QwtLinearColorMap::setMode( Mode mode )
278
234
{
279
235
    d_data->mode = mode;
280
236
}
289
245
}
290
246
 
291
247
/*!
292
 
   Set the color range 
 
248
   Set the color range
293
249
 
294
 
   Add stops at 0.0 and 1.0. 
 
250
   Add stops at 0.0 and 1.0.
295
251
 
296
252
   \param color1 Color used for the minimum value of the value interval
297
253
   \param color2 Color used for the maximum value of the value interval
299
255
   \sa color1(), color2()
300
256
*/
301
257
void QwtLinearColorMap::setColorInterval(
302
 
    const QColor &color1, const QColor &color2)
 
258
    const QColor &color1, const QColor &color2 )
303
259
{
304
260
    d_data->colorStops = ColorStops();
305
 
    d_data->colorStops.insert(0.0, color1);
306
 
    d_data->colorStops.insert(1.0, color2);
 
261
    d_data->colorStops.insert( 0.0, color1 );
 
262
    d_data->colorStops.insert( 1.0, color2 );
307
263
}
308
264
 
309
265
/*!
310
266
   Add a color stop
311
267
 
312
 
   The value has to be in the range [0.0, 1.0]. 
 
268
   The value has to be in the range [0.0, 1.0].
313
269
   F.e. a stop at position 17.0 for a range [10.0,20.0] must be
314
270
   passed as: (17.0 - 10.0) / (20.0 - 10.0)
315
271
 
316
272
   \param value Value between [0.0, 1.0]
317
273
   \param color Color stop
318
274
*/
319
 
void QwtLinearColorMap::addColorStop(double value, const QColor& color)
 
275
void QwtLinearColorMap::addColorStop( double value, const QColor& color )
320
276
{
321
277
    if ( value >= 0.0 && value <= 1.0 )
322
 
        d_data->colorStops.insert(value, color);
 
278
        d_data->colorStops.insert( value, color );
323
279
}
324
280
 
325
281
/*!
326
282
   Return all positions of color stops in increasing order
327
283
*/
328
 
QwtArray<double> QwtLinearColorMap::colorStops() const
 
284
QVector<double> QwtLinearColorMap::colorStops() const
329
285
{
330
286
    return d_data->colorStops.stops();
331
287
}
332
288
 
333
 
/*! 
 
289
/*!
334
290
  \return the first color of the color range
335
291
  \sa setColorInterval()
336
292
*/
337
293
QColor QwtLinearColorMap::color1() const
338
294
{
339
 
    return QColor(d_data->colorStops.rgb(d_data->mode, 0.0));
 
295
    return QColor( d_data->colorStops.rgb( d_data->mode, 0.0 ) );
340
296
}
341
297
 
342
 
/*! 
 
298
/*!
343
299
  \return the second color of the color range
344
300
  \sa setColorInterval()
345
301
*/
346
302
QColor QwtLinearColorMap::color2() const
347
303
{
348
 
    return QColor(d_data->colorStops.rgb(d_data->mode, 1.0));
 
304
    return QColor( d_data->colorStops.rgb( d_data->mode, 1.0 ) );
349
305
}
350
306
 
351
307
/*!
355
311
  \param value Value to map into a rgb value
356
312
*/
357
313
QRgb QwtLinearColorMap::rgb(
358
 
    const QwtDoubleInterval &interval, double value) const
 
314
    const QwtInterval &interval, double value ) const
359
315
{
 
316
    if ( qIsNaN(value) )
 
317
        return qRgba(0, 0, 0, 0);
 
318
 
360
319
    const double width = interval.width();
361
320
 
362
321
    double ratio = 0.0;
363
322
    if ( width > 0.0 )
364
 
        ratio = (value - interval.minValue()) / width;
 
323
        ratio = ( value - interval.minValue() ) / width;
365
324
 
366
 
    return d_data->colorStops.rgb(d_data->mode, ratio);
 
325
    return d_data->colorStops.rgb( d_data->mode, ratio );
367
326
}
368
327
 
369
328
/*!
373
332
  \param value Value to map into a color index
374
333
*/
375
334
unsigned char QwtLinearColorMap::colorIndex(
376
 
    const QwtDoubleInterval &interval, double value) const
 
335
    const QwtInterval &interval, double value ) const
377
336
{
378
337
    const double width = interval.width();
379
338
 
380
 
    if ( width <= 0.0 || value <= interval.minValue() )
 
339
    if ( qIsNaN(value) || width <= 0.0 || value <= interval.minValue() )
381
340
        return 0;
382
341
 
383
342
    if ( value >= interval.maxValue() )
384
 
        return (unsigned char)255;
385
 
 
386
 
    const double ratio = (value - interval.minValue()) / width;
387
 
    
 
343
        return ( unsigned char )255;
 
344
 
 
345
    const double ratio = ( value - interval.minValue() ) / width;
 
346
 
388
347
    unsigned char index;
389
348
    if ( d_data->mode == FixedColors )
390
 
        index = (unsigned char)(ratio * 255); // always floor
 
349
        index = ( unsigned char )( ratio * 255 ); // always floor
391
350
    else
392
 
        index = (unsigned char)qRound(ratio * 255);
 
351
        index = ( unsigned char )qRound( ratio * 255 );
393
352
 
394
353
    return index;
395
354
}
402
361
};
403
362
 
404
363
 
405
 
/*! 
 
364
/*!
406
365
   Constructor
407
366
   \param color Color of the map
408
367
*/
409
 
QwtAlphaColorMap::QwtAlphaColorMap(const QColor &color):
410
 
    QwtColorMap(QwtColorMap::RGB)
 
368
QwtAlphaColorMap::QwtAlphaColorMap( const QColor &color ):
 
369
    QwtColorMap( QwtColorMap::RGB )
411
370
{
412
371
    d_data = new PrivateData;
413
372
    d_data->color = color;
414
 
    d_data->rgb = color.rgb() & qRgba(255, 255, 255, 0);
415
 
}
416
 
 
417
 
/*! 
418
 
   Copy constructor
419
 
   \param other Other color map
420
 
*/
421
 
QwtAlphaColorMap::QwtAlphaColorMap(const QwtAlphaColorMap &other):
422
 
    QwtColorMap(other)
423
 
{
424
 
    d_data = new PrivateData;
425
 
    *this = other;
 
373
    d_data->rgb = color.rgb() & qRgba( 255, 255, 255, 0 );
426
374
}
427
375
 
428
376
//! Destructor
431
379
    delete d_data;
432
380
}
433
381
 
434
 
/*! 
435
 
   Assignment operator
436
 
   \param other Other color map
437
 
   \return *this
438
 
*/
439
 
QwtAlphaColorMap &QwtAlphaColorMap::operator=(
440
 
    const QwtAlphaColorMap &other)
441
 
{
442
 
    QwtColorMap::operator=(other);
443
 
    *d_data = *other.d_data;
444
 
    return *this;
445
 
}
446
 
 
447
 
//! Clone the color map
448
 
QwtColorMap *QwtAlphaColorMap::copy() const
449
 
{
450
 
    QwtAlphaColorMap* map = new QwtAlphaColorMap();
451
 
    *map = *this;
452
 
 
453
 
    return map;
454
 
}
455
 
 
456
382
/*!
457
 
   Set the color 
 
383
   Set the color
458
384
 
459
385
   \param color Color
460
386
   \sa color()
461
387
*/
462
 
void QwtAlphaColorMap::setColor(const QColor &color)
 
388
void QwtAlphaColorMap::setColor( const QColor &color )
463
389
{
464
390
    d_data->color = color;
465
391
    d_data->rgb = color.rgb();
466
392
}
467
393
 
468
 
/*! 
469
 
  \return the color 
 
394
/*!
 
395
  \return the color
470
396
  \sa setColor()
471
397
*/
472
398
QColor QwtAlphaColorMap::color() const
483
409
  \param value Value to map into a rgb value
484
410
  \return rgb value, with an alpha value
485
411
*/
486
 
QRgb QwtAlphaColorMap::rgb(const QwtDoubleInterval &interval,
487
 
    double value) const
 
412
QRgb QwtAlphaColorMap::rgb( const QwtInterval &interval, double value ) const
488
413
{
489
414
    const double width = interval.width();
490
 
    if ( width >= 0.0 )
 
415
    if ( !qIsNaN(value) && width >= 0.0 )
491
416
    {
492
 
        const double ratio = (value - interval.minValue()) / width;
493
 
        int alpha = qRound(255 * ratio);
 
417
        const double ratio = ( value - interval.minValue() ) / width;
 
418
        int alpha = qRound( 255 * ratio );
494
419
        if ( alpha < 0 )
495
420
            alpha = 0;
496
421
        if ( alpha > 255 )
497
422
            alpha = 255;
498
423
 
499
 
        return d_data->rgb | (alpha << 24);
 
424
        return d_data->rgb | ( alpha << 24 );
500
425
    }
501
426
    return d_data->rgb;
502
427
}
503
428
 
504
429
/*!
505
430
  Dummy function, needed to be implemented as it is pure virtual
506
 
  in QwtColorMap. Color indices make no sense in combination with 
 
431
  in QwtColorMap. Color indices make no sense in combination with
507
432
  an alpha channel.
508
433
 
509
434
  \return Always 0
510
435
*/
511
436
unsigned char QwtAlphaColorMap::colorIndex(
512
 
    const QwtDoubleInterval &, double) const
 
437
    const QwtInterval &, double ) const
513
438
{
514
439
    return 0;
515
440
}