1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the Qwt License, Version 1.0
8
*****************************************************************************/
10
#include "qwt_array.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;
22
class QwtLinearColorMap::ColorStops
27
#if QT_VERSION >= 0x040000
32
void insert(double pos, const QColor &color);
33
QRgb rgb(QwtLinearColorMap::Mode, double pos) const;
35
QwtArray<double> stops() const;
48
ColorStop(double p, const QColor &c):
62
inline int findUpper(double pos) const;
63
QwtArray<ColorStop> _stops;
66
void QwtLinearColorMap::ColorStops::insert(double pos, const QColor &color)
68
// Lookups need to be very fast, insertions are not so important.
69
// Anyway, a balanced tree is what we need here. TODO ...
71
if ( pos < 0.0 || pos > 1.0 )
75
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 )
90
#if QT_VERSION < 0x040000
91
_stops.resize(_stops.size() + 1, QGArray::SpeedOptim);
93
_stops.resize(_stops.size() + 1);
95
for ( int i = _stops.size() - 1; i > index; i-- )
96
_stops[i] = _stops[i-1];
100
_stops[index] = ColorStop(pos, color);
103
inline QwtArray<double> QwtLinearColorMap::ColorStops::stops() const
105
QwtArray<double> positions(_stops.size());
106
for ( int i = 0; i < (int)_stops.size(); i++ )
107
positions[i] = _stops[i].pos;
111
inline int QwtLinearColorMap::ColorStops::findUpper(double pos) const
114
int n = _stops.size();
116
const ColorStop *stops = _stops.data();
120
const int half = n >> 1;
121
const int middle = index + half;
123
if ( stops[middle].pos <= pos )
135
inline QRgb QwtLinearColorMap::ColorStops::rgb(
136
QwtLinearColorMap::Mode mode, double pos) const
139
return _stops[0].rgb;
141
return _stops[(int)(_stops.size() - 1)].rgb;
143
const int index = findUpper(pos);
144
if ( mode == FixedColors )
146
return _stops[index-1].rgb;
150
const ColorStop &s1 = _stops[index-1];
151
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);
164
QwtColorMap::QwtColorMap(Format format):
170
QwtColorMap::~QwtColorMap()
175
Build and return a color map of 256 colors
177
The color table is needed for rendering indexed images in combination
178
with using colorIndex().
180
\param interval Range for the values
181
\return A color table, that can be used for a QImage
183
QwtColorTable QwtColorMap::colorTable(
184
const QwtDoubleInterval &interval) const
186
QwtColorTable table(256);
188
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);
198
class QwtLinearColorMap::PrivateData
201
ColorStops colorStops;
202
QwtLinearColorMap::Mode mode;
206
Build a color map with two stops at 0.0 and 1.0. The color
207
at 0.0 is Qt::blue, at 1.0 it is Qt::yellow.
209
\param format Preferred format of the color map
211
QwtLinearColorMap::QwtLinearColorMap(QwtColorMap::Format format):
214
d_data = new PrivateData;
215
d_data->mode = ScaledColors;
217
setColorInterval( Qt::blue, Qt::yellow);
221
QwtLinearColorMap::QwtLinearColorMap(const QwtLinearColorMap &other):
224
d_data = new PrivateData;
229
Build a color map with two stops at 0.0 and 1.0.
231
\param color1 Color used for the minimum value of the value interval
232
\param color2 Color used for the maximum value of the value interval
233
\param format Preferred format of the coor map
235
QwtLinearColorMap::QwtLinearColorMap(const QColor &color1,
236
const QColor &color2, QwtColorMap::Format format):
239
d_data = new PrivateData;
240
d_data->mode = ScaledColors;
241
setColorInterval(color1, color2);
245
QwtLinearColorMap::~QwtLinearColorMap()
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
\brief Set the mode of the color map
271
FixedColors means the color is calculated from the next lower
272
color stop. ScaledColors means the color is calculated
273
by interpolating the colors of the adjacent stops.
277
void QwtLinearColorMap::setMode(Mode mode)
283
\return Mode of the color map
286
QwtLinearColorMap::Mode QwtLinearColorMap::mode() const
294
Add stops at 0.0 and 1.0.
296
\param color1 Color used for the minimum value of the value interval
297
\param color2 Color used for the maximum value of the value interval
299
\sa color1(), color2()
301
void QwtLinearColorMap::setColorInterval(
302
const QColor &color1, const QColor &color2)
304
d_data->colorStops = ColorStops();
305
d_data->colorStops.insert(0.0, color1);
306
d_data->colorStops.insert(1.0, color2);
312
The value has to be in the range [0.0, 1.0].
313
F.e. a stop at position 17.0 for a range [10.0,20.0] must be
314
passed as: (17.0 - 10.0) / (20.0 - 10.0)
316
\param value Value between [0.0, 1.0]
317
\param color Color stop
319
void QwtLinearColorMap::addColorStop(double value, const QColor& color)
321
if ( value >= 0.0 && value <= 1.0 )
322
d_data->colorStops.insert(value, color);
326
Return all positions of color stops in increasing order
328
QwtArray<double> QwtLinearColorMap::colorStops() const
330
return d_data->colorStops.stops();
334
\return the first color of the color range
335
\sa setColorInterval()
337
QColor QwtLinearColorMap::color1() const
339
return QColor(d_data->colorStops.rgb(d_data->mode, 0.0));
343
\return the second color of the color range
344
\sa setColorInterval()
346
QColor QwtLinearColorMap::color2() const
348
return QColor(d_data->colorStops.rgb(d_data->mode, 1.0));
352
Map a value of a given interval into a rgb value
354
\param interval Range for all values
355
\param value Value to map into a rgb value
357
QRgb QwtLinearColorMap::rgb(
358
const QwtDoubleInterval &interval, double value) const
360
const double width = interval.width();
364
ratio = (value - interval.minValue()) / width;
366
return d_data->colorStops.rgb(d_data->mode, ratio);
370
Map a value of a given interval into a color index, between 0 and 255
372
\param interval Range for all values
373
\param value Value to map into a color index
375
unsigned char QwtLinearColorMap::colorIndex(
376
const QwtDoubleInterval &interval, double value) const
378
const double width = interval.width();
380
if ( width <= 0.0 || value <= interval.minValue() )
383
if ( value >= interval.maxValue() )
384
return (unsigned char)255;
386
const double ratio = (value - interval.minValue()) / width;
389
if ( d_data->mode == FixedColors )
390
index = (unsigned char)(ratio * 255); // always floor
392
index = (unsigned char)qRound(ratio * 255);
397
class QwtAlphaColorMap::PrivateData
407
\param color Color of the map
409
QwtAlphaColorMap::QwtAlphaColorMap(const QColor &color):
410
QwtColorMap(QwtColorMap::RGB)
412
d_data = new PrivateData;
413
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;
429
QwtAlphaColorMap::~QwtAlphaColorMap()
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();
462
void QwtAlphaColorMap::setColor(const QColor &color)
464
d_data->color = color;
465
d_data->rgb = color.rgb();
472
QColor QwtAlphaColorMap::color() const
474
return d_data->color;
478
\brief Map a value of a given interval into a alpha value
480
alpha := (value - interval.minValue()) / interval.width();
482
\param interval Range for all values
483
\param value Value to map into a rgb value
484
\return rgb value, with an alpha value
486
QRgb QwtAlphaColorMap::rgb(const QwtDoubleInterval &interval,
489
const double width = interval.width();
492
const double ratio = (value - interval.minValue()) / width;
493
int alpha = qRound(255 * ratio);
499
return d_data->rgb | (alpha << 24);
505
Dummy function, needed to be implemented as it is pure virtual
506
in QwtColorMap. Color indices make no sense in combination with
511
unsigned char QwtAlphaColorMap::colorIndex(
512
const QwtDoubleInterval &, double) const