7
7
* modify it under the terms of the Qwt License, Version 1.0
8
8
*****************************************************************************/
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"
15
#if QT_VERSION < 0x040000
16
#include <qvaluelist.h>
17
typedef QValueVector<QRgb> QwtColorTable;
19
typedef QVector<QRgb> QwtColorTable;
12
#include "qwt_interval.h"
22
15
class QwtLinearColorMap::ColorStops
27
#if QT_VERSION >= 0x040000
20
_stops.reserve( 256 );
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;
35
QwtArray<double> stops() const;
26
QVector<double> stops() const;
62
inline int findUpper(double pos) const;
63
QwtArray<ColorStop> _stops;
53
inline int findUpper( double pos ) const;
54
QVector<ColorStop> _stops;
66
void QwtLinearColorMap::ColorStops::insert(double pos, const QColor &color)
57
void QwtLinearColorMap::ColorStops::insert( double pos, const QColor &color )
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 )
78
#if QT_VERSION < 0x040000
79
_stops.resize(1, QGArray::SpeedOptim);
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 )
90
#if QT_VERSION < 0x040000
91
_stops.resize(_stops.size() + 1, QGArray::SpeedOptim);
93
_stops.resize(_stops.size() + 1);
77
_stops.resize( _stops.size() + 1 );
95
78
for ( int i = _stops.size() - 1; i > index; i-- )
96
79
_stops[i] = _stops[i-1];
100
_stops[index] = ColorStop(pos, color);
83
_stops[index] = ColorStop( pos, color );
103
inline QwtArray<double> QwtLinearColorMap::ColorStops::stops() const
86
inline QVector<double> QwtLinearColorMap::ColorStops::stops() const
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;
111
inline int QwtLinearColorMap::ColorStops::findUpper(double pos) const
94
inline int QwtLinearColorMap::ColorStops::findUpper( double pos ) const
114
97
int n = _stops.size();
116
99
const ColorStop *stops = _stops.data();
120
103
const int half = n >> 1;
121
104
const int middle = index + half;
123
if ( stops[middle].pos <= pos )
106
if ( stops[middle].pos <= pos )
125
108
index = middle + 1;
135
118
inline QRgb QwtLinearColorMap::ColorStops::rgb(
136
QwtLinearColorMap::Mode mode, double pos) const
119
QwtLinearColorMap::Mode mode, double pos ) const
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;
143
const int index = findUpper(pos);
126
const int index = findUpper( pos );
144
127
if ( mode == FixedColors )
146
129
return _stops[index-1].rgb;
150
133
const ColorStop &s1 = _stops[index-1];
151
134
const ColorStop &s2 = _stops[index];
153
const double ratio = (pos - s1.pos) / (s2.pos - s1.pos);
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));
159
return qRgb(r, g, b);
136
const double ratio = ( pos - s1.pos ) / ( s2.pos - s1.pos );
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 ) );
142
return qRgb( r, g, b );
164
QwtColorMap::QwtColorMap(Format format):
147
QwtColorMap::QwtColorMap( Format format ):
175
158
Build and return a color map of 256 colors
177
160
The color table is needed for rendering indexed images in combination
178
with using colorIndex().
161
with using colorIndex().
180
163
\param interval Range for the values
181
164
\return A color table, that can be used for a QImage
183
QwtColorTable QwtColorMap::colorTable(
184
const QwtDoubleInterval &interval) const
166
QVector<QRgb> QwtColorMap::colorTable( const QwtInterval &interval ) const
186
QwtColorTable table(256);
168
QVector<QRgb> table( 256 );
188
170
if ( interval.isValid() )
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 );
202
184
QwtLinearColorMap::Mode mode;
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.
209
191
\param format Preferred format of the color map
211
QwtLinearColorMap::QwtLinearColorMap(QwtColorMap::Format format):
193
QwtLinearColorMap::QwtLinearColorMap( QwtColorMap::Format format ):
194
QwtColorMap( format )
214
196
d_data = new PrivateData;
215
197
d_data->mode = ScaledColors;
217
setColorInterval( Qt::blue, Qt::yellow);
221
QwtLinearColorMap::QwtLinearColorMap(const QwtLinearColorMap &other):
224
d_data = new PrivateData;
199
setColorInterval( Qt::blue, Qt::yellow );
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.
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
235
QwtLinearColorMap::QwtLinearColorMap(const QColor &color1,
236
const QColor &color2, QwtColorMap::Format format):
209
QwtLinearColorMap::QwtLinearColorMap( const QColor &color1,
210
const QColor &color2, QwtColorMap::Format format ):
211
QwtColorMap( format )
239
213
d_data = new PrivateData;
240
214
d_data->mode = ScaledColors;
241
setColorInterval(color1, color2);
215
setColorInterval( color1, color2 );
250
//! Assignment operator
251
QwtLinearColorMap &QwtLinearColorMap::operator=(
252
const QwtLinearColorMap &other)
254
QwtColorMap::operator=(other);
255
*d_data = *other.d_data;
259
//! Clone the color map
260
QwtColorMap *QwtLinearColorMap::copy() const
262
QwtLinearColorMap* map = new QwtLinearColorMap();
269
225
\brief Set the mode of the color map
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.
277
void QwtLinearColorMap::setMode(Mode mode)
233
void QwtLinearColorMap::setMode( Mode mode )
279
235
d_data->mode = mode;
299
255
\sa color1(), color2()
301
257
void QwtLinearColorMap::setColorInterval(
302
const QColor &color1, const QColor &color2)
258
const QColor &color1, const QColor &color2 )
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 );
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)
316
272
\param value Value between [0.0, 1.0]
317
273
\param color Color stop
319
void QwtLinearColorMap::addColorStop(double value, const QColor& color)
275
void QwtLinearColorMap::addColorStop( double value, const QColor& color )
321
277
if ( value >= 0.0 && value <= 1.0 )
322
d_data->colorStops.insert(value, color);
278
d_data->colorStops.insert( value, color );
326
282
Return all positions of color stops in increasing order
328
QwtArray<double> QwtLinearColorMap::colorStops() const
284
QVector<double> QwtLinearColorMap::colorStops() const
330
286
return d_data->colorStops.stops();
334
290
\return the first color of the color range
335
291
\sa setColorInterval()
337
293
QColor QwtLinearColorMap::color1() const
339
return QColor(d_data->colorStops.rgb(d_data->mode, 0.0));
295
return QColor( d_data->colorStops.rgb( d_data->mode, 0.0 ) );
343
299
\return the second color of the color range
344
300
\sa setColorInterval()
346
302
QColor QwtLinearColorMap::color2() const
348
return QColor(d_data->colorStops.rgb(d_data->mode, 1.0));
304
return QColor( d_data->colorStops.rgb( d_data->mode, 1.0 ) );
355
311
\param value Value to map into a rgb value
357
313
QRgb QwtLinearColorMap::rgb(
358
const QwtDoubleInterval &interval, double value) const
314
const QwtInterval &interval, double value ) const
317
return qRgba(0, 0, 0, 0);
360
319
const double width = interval.width();
362
321
double ratio = 0.0;
363
322
if ( width > 0.0 )
364
ratio = (value - interval.minValue()) / width;
323
ratio = ( value - interval.minValue() ) / width;
366
return d_data->colorStops.rgb(d_data->mode, ratio);
325
return d_data->colorStops.rgb( d_data->mode, ratio );
373
332
\param value Value to map into a color index
375
334
unsigned char QwtLinearColorMap::colorIndex(
376
const QwtDoubleInterval &interval, double value) const
335
const QwtInterval &interval, double value ) const
378
337
const double width = interval.width();
380
if ( width <= 0.0 || value <= interval.minValue() )
339
if ( qIsNaN(value) || width <= 0.0 || value <= interval.minValue() )
383
342
if ( value >= interval.maxValue() )
384
return (unsigned char)255;
386
const double ratio = (value - interval.minValue()) / width;
343
return ( unsigned char )255;
345
const double ratio = ( value - interval.minValue() ) / width;
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
392
index = (unsigned char)qRound(ratio * 255);
351
index = ( unsigned char )qRound( ratio * 255 );
407
366
\param color Color of the map
409
QwtAlphaColorMap::QwtAlphaColorMap(const QColor &color):
410
QwtColorMap(QwtColorMap::RGB)
368
QwtAlphaColorMap::QwtAlphaColorMap( const QColor &color ):
369
QwtColorMap( QwtColorMap::RGB )
412
371
d_data = new PrivateData;
413
372
d_data->color = color;
414
d_data->rgb = color.rgb() & qRgba(255, 255, 255, 0);
419
\param other Other color map
421
QwtAlphaColorMap::QwtAlphaColorMap(const QwtAlphaColorMap &other):
424
d_data = new PrivateData;
373
d_data->rgb = color.rgb() & qRgba( 255, 255, 255, 0 );
436
\param other Other color map
439
QwtAlphaColorMap &QwtAlphaColorMap::operator=(
440
const QwtAlphaColorMap &other)
442
QwtColorMap::operator=(other);
443
*d_data = *other.d_data;
447
//! Clone the color map
448
QwtColorMap *QwtAlphaColorMap::copy() const
450
QwtAlphaColorMap* map = new QwtAlphaColorMap();
459
385
\param color Color
462
void QwtAlphaColorMap::setColor(const QColor &color)
388
void QwtAlphaColorMap::setColor( const QColor &color )
464
390
d_data->color = color;
465
391
d_data->rgb = color.rgb();
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
486
QRgb QwtAlphaColorMap::rgb(const QwtDoubleInterval &interval,
412
QRgb QwtAlphaColorMap::rgb( const QwtInterval &interval, double value ) const
489
414
const double width = interval.width();
415
if ( !qIsNaN(value) && width >= 0.0 )
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 );
496
421
if ( alpha > 255 )
499
return d_data->rgb | (alpha << 24);
424
return d_data->rgb | ( alpha << 24 );
501
426
return d_data->rgb;
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.
511
436
unsigned char QwtAlphaColorMap::colorIndex(
512
const QwtDoubleInterval &, double) const
437
const QwtInterval &, double ) const