Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_array.h"
00011 #include "qwt_math.h"
00012 #include "qwt_double_interval.h"
00013 #include "qwt_color_map.h"
00014
00015 #if QT_VERSION < 0x040000
00016 #include <qvaluelist.h>
00017 typedef QValueVector<QRgb> QwtColorTable;
00018 #else
00019 typedef QVector<QRgb> QwtColorTable;
00020 #endif
00021
00022 class QwtLinearColorMap::ColorStops
00023 {
00024 public:
00025 ColorStops()
00026 {
00027 #if QT_VERSION >= 0x040000
00028 _stops.reserve(256);
00029 #endif
00030 }
00031
00032 void insert(double pos, const QColor &color);
00033 QRgb rgb(QwtLinearColorMap::Mode, double pos) const;
00034
00035 QwtArray<double> stops() const;
00036
00037 private:
00038
00039 class ColorStop
00040 {
00041 public:
00042 ColorStop():
00043 pos(0.0),
00044 rgb(0)
00045 {
00046 };
00047
00048 ColorStop(double p, const QColor &c):
00049 pos(p),
00050 rgb(c.rgb())
00051 {
00052 r = qRed(rgb);
00053 g = qGreen(rgb);
00054 b = qBlue(rgb);
00055 }
00056
00057 double pos;
00058 QRgb rgb;
00059 int r, g, b;
00060 };
00061
00062 inline int findUpper(double pos) const;
00063 QwtArray<ColorStop> _stops;
00064 };
00065
00066 void QwtLinearColorMap::ColorStops::insert(double pos, const QColor &color)
00067 {
00068
00069
00070
00071 if ( pos < 0.0 || pos > 1.0 )
00072 return;
00073
00074 int index;
00075 if ( _stops.size() == 0 )
00076 {
00077 index = 0;
00078 #if QT_VERSION < 0x040000
00079 _stops.resize(1, QGArray::SpeedOptim);
00080 #else
00081 _stops.resize(1);
00082 #endif
00083 }
00084 else
00085 {
00086 index = findUpper(pos);
00087 if ( index == (int)_stops.size() ||
00088 qwtAbs(_stops[index].pos - pos) >= 0.001 )
00089 {
00090 #if QT_VERSION < 0x040000
00091 _stops.resize(_stops.size() + 1, QGArray::SpeedOptim);
00092 #else
00093 _stops.resize(_stops.size() + 1);
00094 #endif
00095 for ( int i = _stops.size() - 1; i > index; i-- )
00096 _stops[i] = _stops[i-1];
00097 }
00098 }
00099
00100 _stops[index] = ColorStop(pos, color);
00101 }
00102
00103 inline QwtArray<double> QwtLinearColorMap::ColorStops::stops() const
00104 {
00105 QwtArray<double> positions(_stops.size());
00106 for ( int i = 0; i < (int)_stops.size(); i++ )
00107 positions[i] = _stops[i].pos;
00108 return positions;
00109 }
00110
00111 inline int QwtLinearColorMap::ColorStops::findUpper(double pos) const
00112 {
00113 int index = 0;
00114 int n = _stops.size();
00115
00116 const ColorStop *stops = _stops.data();
00117
00118 while (n > 0)
00119 {
00120 const int half = n >> 1;
00121 const int middle = index + half;
00122
00123 if ( stops[middle].pos <= pos )
00124 {
00125 index = middle + 1;
00126 n -= half + 1;
00127 }
00128 else
00129 n = half;
00130 }
00131
00132 return index;
00133 }
00134
00135 inline QRgb QwtLinearColorMap::ColorStops::rgb(
00136 QwtLinearColorMap::Mode mode, double pos) const
00137 {
00138 if ( pos <= 0.0 )
00139 return _stops[0].rgb;
00140 if ( pos >= 1.0 )
00141 return _stops[(int)(_stops.size() - 1)].rgb;
00142
00143 const int index = findUpper(pos);
00144 if ( mode == FixedColors )
00145 {
00146 return _stops[index-1].rgb;
00147 }
00148 else
00149 {
00150 const ColorStop &s1 = _stops[index-1];
00151 const ColorStop &s2 = _stops[index];
00152
00153 const double ratio = (pos - s1.pos) / (s2.pos - s1.pos);
00154
00155 const int r = s1.r + qRound(ratio * (s2.r - s1.r));
00156 const int g = s1.g + qRound(ratio * (s2.g - s1.g));
00157 const int b = s1.b + qRound(ratio * (s2.b - s1.b));
00158
00159 return qRgb(r, g, b);
00160 }
00161 }
00162
00164 QwtColorMap::QwtColorMap(Format format):
00165 d_format(format)
00166 {
00167 }
00168
00170 QwtColorMap::~QwtColorMap()
00171 {
00172 }
00173
00183 QwtColorTable QwtColorMap::colorTable(
00184 const QwtDoubleInterval &interval) const
00185 {
00186 QwtColorTable table(256);
00187
00188 if ( interval.isValid() )
00189 {
00190 const double step = interval.width() / (table.size() - 1);
00191 for ( int i = 0; i < (int) table.size(); i++ )
00192 table[i] = rgb(interval, interval.minValue() + step * i);
00193 }
00194
00195 return table;
00196 }
00197
00198 class QwtLinearColorMap::PrivateData
00199 {
00200 public:
00201 ColorStops colorStops;
00202 QwtLinearColorMap::Mode mode;
00203 };
00204
00211 QwtLinearColorMap::QwtLinearColorMap(QwtColorMap::Format format):
00212 QwtColorMap(format)
00213 {
00214 d_data = new PrivateData;
00215 d_data->mode = ScaledColors;
00216
00217 setColorInterval( Qt::blue, Qt::yellow);
00218 }
00219
00221 QwtLinearColorMap::QwtLinearColorMap(const QwtLinearColorMap &other):
00222 QwtColorMap(other)
00223 {
00224 d_data = new PrivateData;
00225 *this = other;
00226 }
00227
00235 QwtLinearColorMap::QwtLinearColorMap(const QColor &color1,
00236 const QColor &color2, QwtColorMap::Format format):
00237 QwtColorMap(format)
00238 {
00239 d_data = new PrivateData;
00240 d_data->mode = ScaledColors;
00241 setColorInterval(color1, color2);
00242 }
00243
00245 QwtLinearColorMap::~QwtLinearColorMap()
00246 {
00247 delete d_data;
00248 }
00249
00251 QwtLinearColorMap &QwtLinearColorMap::operator=(
00252 const QwtLinearColorMap &other)
00253 {
00254 QwtColorMap::operator=(other);
00255 *d_data = *other.d_data;
00256 return *this;
00257 }
00258
00260 QwtColorMap *QwtLinearColorMap::copy() const
00261 {
00262 QwtLinearColorMap* map = new QwtLinearColorMap();
00263 *map = *this;
00264
00265 return map;
00266 }
00267
00277 void QwtLinearColorMap::setMode(Mode mode)
00278 {
00279 d_data->mode = mode;
00280 }
00281
00286 QwtLinearColorMap::Mode QwtLinearColorMap::mode() const
00287 {
00288 return d_data->mode;
00289 }
00290
00301 void QwtLinearColorMap::setColorInterval(
00302 const QColor &color1, const QColor &color2)
00303 {
00304 d_data->colorStops = ColorStops();
00305 d_data->colorStops.insert(0.0, color1);
00306 d_data->colorStops.insert(1.0, color2);
00307 }
00308
00319 void QwtLinearColorMap::addColorStop(double value, const QColor& color)
00320 {
00321 if ( value >= 0.0 && value <= 1.0 )
00322 d_data->colorStops.insert(value, color);
00323 }
00324
00328 QwtArray<double> QwtLinearColorMap::colorStops() const
00329 {
00330 return d_data->colorStops.stops();
00331 }
00332
00337 QColor QwtLinearColorMap::color1() const
00338 {
00339 return QColor(d_data->colorStops.rgb(d_data->mode, 0.0));
00340 }
00341
00346 QColor QwtLinearColorMap::color2() const
00347 {
00348 return QColor(d_data->colorStops.rgb(d_data->mode, 1.0));
00349 }
00350
00357 QRgb QwtLinearColorMap::rgb(
00358 const QwtDoubleInterval &interval, double value) const
00359 {
00360 const double width = interval.width();
00361
00362 double ratio = 0.0;
00363 if ( width > 0.0 )
00364 ratio = (value - interval.minValue()) / width;
00365
00366 return d_data->colorStops.rgb(d_data->mode, ratio);
00367 }
00368
00375 unsigned char QwtLinearColorMap::colorIndex(
00376 const QwtDoubleInterval &interval, double value) const
00377 {
00378 const double width = interval.width();
00379
00380 if ( width <= 0.0 || value <= interval.minValue() )
00381 return 0;
00382
00383 if ( value >= interval.maxValue() )
00384 return (unsigned char)255;
00385
00386 const double ratio = (value - interval.minValue()) / width;
00387
00388 unsigned char index;
00389 if ( d_data->mode == FixedColors )
00390 index = (unsigned char)(ratio * 255);
00391 else
00392 index = (unsigned char)qRound(ratio * 255);
00393
00394 return index;
00395 }
00396
00397 class QwtAlphaColorMap::PrivateData
00398 {
00399 public:
00400 QColor color;
00401 QRgb rgb;
00402 };
00403
00404
00409 QwtAlphaColorMap::QwtAlphaColorMap(const QColor &color):
00410 QwtColorMap(QwtColorMap::RGB)
00411 {
00412 d_data = new PrivateData;
00413 d_data->color = color;
00414 d_data->rgb = color.rgb() & qRgba(255, 255, 255, 0);
00415 }
00416
00421 QwtAlphaColorMap::QwtAlphaColorMap(const QwtAlphaColorMap &other):
00422 QwtColorMap(other)
00423 {
00424 d_data = new PrivateData;
00425 *this = other;
00426 }
00427
00429 QwtAlphaColorMap::~QwtAlphaColorMap()
00430 {
00431 delete d_data;
00432 }
00433
00439 QwtAlphaColorMap &QwtAlphaColorMap::operator=(
00440 const QwtAlphaColorMap &other)
00441 {
00442 QwtColorMap::operator=(other);
00443 *d_data = *other.d_data;
00444 return *this;
00445 }
00446
00448 QwtColorMap *QwtAlphaColorMap::copy() const
00449 {
00450 QwtAlphaColorMap* map = new QwtAlphaColorMap();
00451 *map = *this;
00452
00453 return map;
00454 }
00455
00462 void QwtAlphaColorMap::setColor(const QColor &color)
00463 {
00464 d_data->color = color;
00465 d_data->rgb = color.rgb();
00466 }
00467
00472 QColor QwtAlphaColorMap::color() const
00473 {
00474 return d_data->color;
00475 }
00476
00486 QRgb QwtAlphaColorMap::rgb(const QwtDoubleInterval &interval,
00487 double value) const
00488 {
00489 const double width = interval.width();
00490 if ( width >= 0.0 )
00491 {
00492 const double ratio = (value - interval.minValue()) / width;
00493 int alpha = qRound(255 * ratio);
00494 if ( alpha < 0 )
00495 alpha = 0;
00496 if ( alpha > 255 )
00497 alpha = 255;
00498
00499 return d_data->rgb | (alpha << 24);
00500 }
00501 return d_data->rgb;
00502 }
00503
00511 unsigned char QwtAlphaColorMap::colorIndex(
00512 const QwtDoubleInterval &, double) const
00513 {
00514 return 0;
00515 }