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(const QwtDoubleInterval &interval,
360
const double ratio = (value - interval.minValue()) / interval.width();
361
return d_data->colorStops.rgb(d_data->mode, ratio);
365
Map a value of a given interval into a color index, between 0 and 255
367
\param interval Range for all values
368
\param value Value to map into a color index
370
unsigned char QwtLinearColorMap::colorIndex(
371
const QwtDoubleInterval &interval, double value) const
373
if ( !interval.isValid() || value <= interval.minValue() )
376
if ( value >= interval.maxValue() )
377
return (unsigned char)255;
379
const double ratio = (value - interval.minValue()) / interval.width();
382
if ( d_data->mode == FixedColors )
383
index = (unsigned char)(ratio * 255); // always floor
385
index = (unsigned char)qRound(ratio * 255);
390
class QwtAlphaColorMap::PrivateData
400
\param color Color of the map
402
QwtAlphaColorMap::QwtAlphaColorMap(const QColor &color):
403
QwtColorMap(QwtColorMap::RGB)
405
d_data = new PrivateData;
406
d_data->color = color;
407
d_data->rgb = color.rgb() & qRgba(255, 255, 255, 0);
412
\param other Other color map
414
QwtAlphaColorMap::QwtAlphaColorMap(const QwtAlphaColorMap &other):
417
d_data = new PrivateData;
422
QwtAlphaColorMap::~QwtAlphaColorMap()
429
\param other Other color map
432
QwtAlphaColorMap &QwtAlphaColorMap::operator=(
433
const QwtAlphaColorMap &other)
435
QwtColorMap::operator=(other);
436
*d_data = *other.d_data;
440
//! Clone the color map
441
QwtColorMap *QwtAlphaColorMap::copy() const
443
QwtAlphaColorMap* map = new QwtAlphaColorMap();
455
void QwtAlphaColorMap::setColor(const QColor &color)
457
d_data->color = color;
458
d_data->rgb = color.rgb();
465
QColor QwtAlphaColorMap::color() const
467
return d_data->color;
471
\brief Map a value of a given interval into a alpha value
473
alpha := (value - interval.minValue()) / interval.width();
475
\param interval Range for all values
476
\param value Value to map into a rgb value
477
\return rgb value, with an alpha value
479
QRgb QwtAlphaColorMap::rgb(const QwtDoubleInterval &interval,
482
if ( interval.isValid() )
484
const double ratio = (value - interval.minValue()) / interval.width();
485
int alpha = qRound(255 * ratio);
491
return d_data->rgb | (alpha << 24);
497
Dummy function, needed to be implemented as it is pure virtual
498
in QwtColorMap. Color indices make no sense in combination with
503
unsigned char QwtAlphaColorMap::colorIndex(
504
const QwtDoubleInterval &, double) const