qwt_color_map.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_color_map.h"
00011 #include "qwt_math.h"
00012 #include "qwt_interval.h"
00013 
00014 #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
00015 
00016 /* 
00017   "-ftree-partial-pre" ( introduced with gcc 4.8 ) does miracles in
00018   QwtColorMap::colorIndex(). When being used very often - like in 
00019   QwtPlotSpectrogram::renderTile() - time goes down by ~50%.
00020 
00021   clang 3.3 is out of the box ( -O2 ) fast for QwtColorMap::colorIndex(), 
00022   but also ~33% faster when rendering the image through QwtLinearColorMap::rgb() 
00023 */
00024 
00025 #define QWT_GCC_OPTIMIZE 1
00026 
00027 #endif
00028 
00029 static inline QRgb qwtHsvToRgb( int h, int s, int v, int a )
00030 {
00031 #if 0
00032     return QColor::fromHsv( h, s, v, a ).rgb();
00033 #else
00034 
00035     const double vs = v * s / 255.0;
00036     const int p = v - qRound( vs );
00037 
00038     switch( h / 60 ) 
00039     {
00040         case 0:
00041         {
00042             const double r = ( 60 - h ) / 60.0;
00043             return qRgba( v, v - qRound( r * vs ), p, a );
00044         }
00045         case 1:
00046         {
00047             const double r = ( h - 60 ) / 60.0;
00048             return qRgba( v - qRound( r * vs ), v, p, a );
00049         }
00050         case 2:
00051         {
00052             const double r = ( 180 - h ) / 60.0;
00053             return qRgba( p, v, v - qRound( r * vs ), a );
00054         }
00055         case 3:
00056         {
00057             const double r = ( h - 180 ) / 60.0;
00058             return qRgba( p, v - qRound( r * vs ), v, a );
00059         }
00060         case 4:
00061         {
00062             const double r = ( 300 - h ) / 60.0;
00063             return qRgba( v - qRound( r * vs ), p, v, a );
00064         }
00065         case 5:
00066         default:
00067         {
00068             const double r = ( h - 300 ) / 60.0;
00069             return qRgba( v, p, v - qRound( r * vs ), a );
00070         }
00071     }
00072 #endif
00073 }
00074 
00075 class QwtLinearColorMap::ColorStops
00076 {
00077 public:
00078     ColorStops():
00079         d_doAlpha( false )
00080     {
00081         d_stops.reserve( 256 );
00082     }
00083 
00084     void insert( double pos, const QColor &color );
00085     QRgb rgb( QwtLinearColorMap::Mode, double pos ) const;
00086 
00087     QVector<double> stops() const;
00088 
00089 private:
00090 
00091     class ColorStop
00092     {
00093     public:
00094         ColorStop():
00095             pos( 0.0 ),
00096             rgb( 0 )
00097         {
00098         };
00099 
00100         ColorStop( double p, const QColor &c ):
00101             pos( p ),
00102             rgb( c.rgba() )
00103         {
00104             r = qRed( rgb );
00105             g = qGreen( rgb );
00106             b = qBlue( rgb );
00107             a = qAlpha( rgb );
00108 
00109             /* 
00110                 when mapping a value to rgb we will have to calcualate: 
00111                    - const int v = int( ( s1.v0 + ratio * s1.vStep ) + 0.5 );
00112 
00113                 Thus adding 0.5 ( for rounding ) can be done in advance
00114              */
00115             r0 = r + 0.5;
00116             g0 = g + 0.5;
00117             b0 = b + 0.5;
00118             a0 = a + 0.5;
00119 
00120             rStep = gStep = bStep = aStep = 0.0;
00121             posStep = 0.0;
00122         }
00123 
00124         void updateSteps( const ColorStop &nextStop )
00125         {
00126             rStep = nextStop.r - r;
00127             gStep = nextStop.g - g;
00128             bStep = nextStop.b - b;
00129             aStep = nextStop.a - a;
00130             posStep = nextStop.pos - pos;
00131         }
00132 
00133         double pos;
00134         QRgb rgb;
00135         int r, g, b, a;
00136 
00137         // precalculated values
00138         double rStep, gStep, bStep, aStep;
00139         double r0, g0, b0, a0;
00140         double posStep;
00141     };
00142 
00143     inline int findUpper( double pos ) const;
00144     QVector<ColorStop> d_stops;
00145     bool d_doAlpha;
00146 };
00147 
00148 void QwtLinearColorMap::ColorStops::insert( double pos, const QColor &color )
00149 {
00150     // Lookups need to be very fast, insertions are not so important.
00151     // Anyway, a balanced tree is what we need here. TODO ...
00152 
00153     if ( pos < 0.0 || pos > 1.0 )
00154         return;
00155 
00156     int index;
00157     if ( d_stops.size() == 0 )
00158     {
00159         index = 0;
00160         d_stops.resize( 1 );
00161     }
00162     else
00163     {
00164         index = findUpper( pos );
00165         if ( index == d_stops.size() ||
00166                 qAbs( d_stops[index].pos - pos ) >= 0.001 )
00167         {
00168             d_stops.resize( d_stops.size() + 1 );
00169             for ( int i = d_stops.size() - 1; i > index; i-- )
00170                 d_stops[i] = d_stops[i-1];
00171         }
00172     }
00173 
00174     d_stops[index] = ColorStop( pos, color );
00175     if ( color.alpha() != 255 )
00176         d_doAlpha = true;
00177 
00178     if ( index > 0 )
00179         d_stops[index-1].updateSteps( d_stops[index] );
00180 
00181     if ( index < d_stops.size() - 1 )
00182         d_stops[index].updateSteps( d_stops[index+1] );
00183 }
00184 
00185 inline QVector<double> QwtLinearColorMap::ColorStops::stops() const
00186 {
00187     QVector<double> positions( d_stops.size() );
00188     for ( int i = 0; i < d_stops.size(); i++ )
00189         positions[i] = d_stops[i].pos;
00190     return positions;
00191 }
00192 
00193 inline int QwtLinearColorMap::ColorStops::findUpper( double pos ) const
00194 {
00195     int index = 0;
00196     int n = d_stops.size();
00197 
00198     const ColorStop *stops = d_stops.data();
00199 
00200     while ( n > 0 )
00201     {
00202         const int half = n >> 1;
00203         const int middle = index + half;
00204 
00205         if ( stops[middle].pos <= pos )
00206         {
00207             index = middle + 1;
00208             n -= half + 1;
00209         }
00210         else
00211             n = half;
00212     }
00213 
00214     return index;
00215 }
00216 
00217 inline QRgb QwtLinearColorMap::ColorStops::rgb(
00218     QwtLinearColorMap::Mode mode, double pos ) const
00219 {
00220     if ( pos <= 0.0 )
00221         return d_stops[0].rgb;
00222     if ( pos >= 1.0 )
00223         return d_stops[ d_stops.size() - 1 ].rgb;
00224 
00225     const int index = findUpper( pos );
00226     if ( mode == FixedColors )
00227     {
00228         return d_stops[index-1].rgb;
00229     }
00230     else
00231     {
00232         const ColorStop &s1 = d_stops[index-1];
00233 
00234         const double ratio = ( pos - s1.pos ) / ( s1.posStep );
00235 
00236         const int r = int( s1.r0 + ratio * s1.rStep );
00237         const int g = int( s1.g0 + ratio * s1.gStep );
00238         const int b = int( s1.b0 + ratio * s1.bStep );
00239 
00240         if ( d_doAlpha )
00241         {
00242             if ( s1.aStep )
00243             {
00244                 const int a = int( s1.a0 + ratio * s1.aStep );
00245                 return qRgba( r, g, b, a );
00246             }
00247             else
00248             {
00249                 return qRgba( r, g, b, s1.a );
00250             }
00251         }
00252         else
00253         {
00254             return qRgb( r, g, b );
00255         }
00256     }
00257 }
00258 
00263 QwtColorMap::QwtColorMap( Format format ):
00264     d_format( format )
00265 {
00266 }
00267 
00269 QwtColorMap::~QwtColorMap()
00270 {
00271 }
00272 
00278 void QwtColorMap::setFormat( Format format )
00279 {
00280     d_format = format;
00281 }
00282 
00283 #ifdef QWT_GCC_OPTIMIZE
00284 #pragma GCC push_options
00285 #pragma GCC optimize("tree-partial-pre")
00286 #endif
00287 
00297 uint QwtColorMap::colorIndex( int numColors,
00298     const QwtInterval &interval, double value ) const
00299 {
00300 #ifdef QWT_GCC_OPTIMIZE
00301     // accessing value here somehow makes gcc 4.8.1 to create
00302     // significantly faster assembler code
00303     if ( ((uchar *)&value)[0] ) asm("");
00304         asm("");
00305 #endif
00306 
00307     const double width = interval.width();
00308     if ( width <= 0.0 )
00309         return 0;
00310 
00311     if ( value <= interval.minValue() )
00312         return 0;
00313 
00314     const int maxIndex = numColors - 1;
00315     if ( value >= interval.maxValue() )
00316         return maxIndex;
00317 
00318     const double v = maxIndex * ( ( value - interval.minValue() ) / width );
00319     return static_cast<unsigned int>( v + 0.5 );
00320 }
00321 
00322 #ifdef QWT_GCC_OPTIMIZE
00323 #pragma GCC pop_options
00324 #endif
00325 
00334 QVector<QRgb> QwtColorMap::colorTable256() const
00335 {
00336     QVector<QRgb> table( 256 );
00337 
00338     const QwtInterval interval( 0, 256 );
00339 
00340     for ( int i = 0; i < 256; i++ )
00341         table[i] = rgb( interval, i );
00342 
00343     return table;
00344 }
00345 
00355 QVector<QRgb> QwtColorMap::colorTable( int numColors ) const
00356 {
00357     QVector<QRgb> table( numColors );
00358 
00359     const QwtInterval interval( 0.0, 1.0 );
00360 
00361     const double step = 1.0 / ( numColors - 1 );
00362     for ( int i = 0; i < numColors; i++ )
00363         table[i] = rgb( interval, step * i );
00364 
00365     return table;
00366 }
00367 
00368 class QwtLinearColorMap::PrivateData
00369 {
00370 public:
00371     ColorStops colorStops;
00372     QwtLinearColorMap::Mode mode;
00373 };
00374 
00381 QwtLinearColorMap::QwtLinearColorMap( QwtColorMap::Format format ):
00382     QwtColorMap( format )
00383 {
00384     d_data = new PrivateData;
00385     d_data->mode = ScaledColors;
00386 
00387     setColorInterval( Qt::blue, Qt::yellow );
00388 }
00389 
00397 QwtLinearColorMap::QwtLinearColorMap( const QColor &color1,
00398         const QColor &color2, QwtColorMap::Format format ):
00399     QwtColorMap( format )
00400 {
00401     d_data = new PrivateData;
00402     d_data->mode = ScaledColors;
00403     setColorInterval( color1, color2 );
00404 }
00405 
00407 QwtLinearColorMap::~QwtLinearColorMap()
00408 {
00409     delete d_data;
00410 }
00411 
00421 void QwtLinearColorMap::setMode( Mode mode )
00422 {
00423     d_data->mode = mode;
00424 }
00425 
00430 QwtLinearColorMap::Mode QwtLinearColorMap::mode() const
00431 {
00432     return d_data->mode;
00433 }
00434 
00445 void QwtLinearColorMap::setColorInterval(
00446     const QColor &color1, const QColor &color2 )
00447 {
00448     d_data->colorStops = ColorStops();
00449     d_data->colorStops.insert( 0.0, color1 );
00450     d_data->colorStops.insert( 1.0, color2 );
00451 }
00452 
00463 void QwtLinearColorMap::addColorStop( double value, const QColor& color )
00464 {
00465     if ( value >= 0.0 && value <= 1.0 )
00466         d_data->colorStops.insert( value, color );
00467 }
00468 
00472 QVector<double> QwtLinearColorMap::colorStops() const
00473 {
00474     return d_data->colorStops.stops();
00475 }
00476 
00481 QColor QwtLinearColorMap::color1() const
00482 {
00483     return QColor( d_data->colorStops.rgb( d_data->mode, 0.0 ) );
00484 }
00485 
00490 QColor QwtLinearColorMap::color2() const
00491 {
00492     return QColor( d_data->colorStops.rgb( d_data->mode, 1.0 ) );
00493 }
00494 
00503 QRgb QwtLinearColorMap::rgb(
00504     const QwtInterval &interval, double value ) const
00505 {
00506     const double width = interval.width();
00507     if ( width <= 0.0 )
00508         return 0u;
00509 
00510     const double ratio = ( value - interval.minValue() ) / width;
00511     return d_data->colorStops.rgb( d_data->mode, ratio );
00512 }
00513 
00514 #ifdef QWT_GCC_OPTIMIZE
00515 #pragma GCC push_options
00516 #pragma GCC optimize("tree-partial-pre")
00517 #endif
00518 
00529 uint QwtLinearColorMap::colorIndex( int numColors,
00530     const QwtInterval &interval, double value ) const
00531 {
00532 #ifdef QWT_GCC_OPTIMIZE
00533     // accessing value here somehow makes gcc 4.8.1 to create
00534     // significantly faster assembler code
00535     if ( ((uchar *)&value)[0] ) asm("");
00536 #endif
00537 
00538     const double width = interval.width();
00539     if ( width <= 0.0 )
00540         return 0;
00541 
00542     if ( value <= interval.minValue() )
00543         return 0;
00544 
00545     if ( value >= interval.maxValue() )
00546         return numColors - 1;
00547 
00548     const double v = ( numColors - 1 ) * ( value - interval.minValue() ) / width;
00549     return static_cast<unsigned int>( ( d_data->mode == FixedColors ) ? v : v + 0.5 );
00550 }
00551 
00552 #ifdef QWT_GCC_OPTIMIZE
00553 #pragma GCC pop_options
00554 #endif
00555 
00556 class QwtAlphaColorMap::PrivateData
00557 {
00558 public:
00559     PrivateData():
00560         alpha1(0),
00561         alpha2(255)
00562     {
00563     }
00564 
00565     int alpha1, alpha2;
00566 
00567     QColor color;
00568     QRgb rgb;
00569 
00570     QRgb rgbMin;
00571     QRgb rgbMax;
00572 };
00573 
00574 
00584 QwtAlphaColorMap::QwtAlphaColorMap( const QColor &color ):
00585     QwtColorMap( QwtColorMap::RGB )
00586 {
00587     d_data = new PrivateData;
00588     setColor( color );
00589 }
00590 
00592 QwtAlphaColorMap::~QwtAlphaColorMap()
00593 {
00594     delete d_data;
00595 }
00596 
00603 void QwtAlphaColorMap::setColor( const QColor &color )
00604 {
00605     d_data->color = color;
00606     d_data->rgb = color.rgb() & qRgba( 255, 255, 255, 0 );
00607 
00608     d_data->rgbMin = d_data->rgb | ( d_data->alpha1 << 24 );
00609     d_data->rgbMax = d_data->rgb | ( d_data->alpha2 << 24 );
00610 }
00611 
00616 QColor QwtAlphaColorMap::color() const
00617 {
00618     return d_data->color;
00619 }
00620 
00632 void QwtAlphaColorMap::setAlphaInterval( int alpha1, int alpha2 )
00633 {
00634     d_data->alpha1 = qBound( 0, alpha1, 255 );
00635     d_data->alpha2 = qBound( 0, alpha2, 255 );
00636 
00637     d_data->rgbMin = d_data->rgb | ( alpha1 << 24 );
00638     d_data->rgbMax = d_data->rgb | ( alpha2 << 24 );
00639 }
00640 
00645 int QwtAlphaColorMap::alpha1() const
00646 {
00647     return d_data->alpha1;
00648 }
00649 
00654 int QwtAlphaColorMap::alpha2() const
00655 {
00656     return d_data->alpha2;
00657 }
00658 
00667 QRgb QwtAlphaColorMap::rgb( const QwtInterval &interval, double value ) const
00668 {
00669     const double width = interval.width();
00670     if ( width <= 0.0 )
00671         return 0u;
00672 
00673     if ( value <= interval.minValue() )
00674         return d_data->rgb;
00675 
00676     if ( value >= interval.maxValue() )
00677         return d_data->rgbMax;
00678 
00679     const double ratio = ( value - interval.minValue() ) / width;
00680     const int alpha = d_data->alpha1 + qRound( ratio * ( d_data->alpha2 - d_data->alpha1 ) );
00681 
00682     return d_data->rgb | ( alpha << 24 );
00683 }
00684 
00685 class QwtHueColorMap::PrivateData
00686 {
00687 public:
00688     PrivateData();
00689 
00690     void updateTable();
00691 
00692     int hue1, hue2;
00693     int saturation;
00694     int value;
00695     int alpha;
00696 
00697     QRgb rgbMin;
00698     QRgb rgbMax;
00699 
00700     QRgb rgbTable[360];
00701 };
00702 
00703 QwtHueColorMap::PrivateData::PrivateData():
00704     hue1(0),
00705     hue2(359),
00706     saturation(255),
00707     value(255),
00708     alpha(255)
00709 {
00710     updateTable();
00711 }
00712 
00713 void QwtHueColorMap::PrivateData::updateTable()
00714 {
00715     const int p = qRound( value * ( 255 - saturation ) / 255.0 );
00716     const double vs = value * saturation / 255.0;
00717 
00718     for ( int i = 0; i < 60; i++ )
00719     {
00720         const double r = ( 60 - i ) / 60.0;
00721         rgbTable[i] = qRgba( value, qRound( value - r * vs ), p, alpha );
00722     }
00723 
00724     for ( int i = 60; i < 120; i++ )
00725     {
00726         const double r = ( i - 60 ) / 60.0;
00727         rgbTable[i] = qRgba( qRound( value - r * vs ), value, p, alpha );
00728     }
00729 
00730     for ( int i = 120; i < 180; i++ )
00731     {
00732         const double r = ( 180 - i ) / 60.0;
00733         rgbTable[i] = qRgba( p, value, qRound( value - r * vs ), alpha );
00734     }
00735 
00736     for ( int i = 180; i < 240; i++ )
00737     {
00738         const double r = ( i - 180 ) / 60.0;
00739         rgbTable[i] = qRgba( p, qRound( value - r * vs ), value, alpha );
00740     }
00741 
00742     for ( int i = 240; i < 300; i++ )
00743     {
00744         const double r = ( 300 - i ) / 60.0;
00745         rgbTable[i] = qRgba( qRound( value - r * vs ), p, value, alpha );
00746     }
00747 
00748     for ( int i = 300; i < 360; i++ )
00749     {
00750         const double r = ( i - 300 ) / 60.0;
00751         rgbTable[i] = qRgba( value, p, qRound( value - r * vs ), alpha );
00752     }
00753 
00754     rgbMin = rgbTable[ hue1 % 360 ];
00755     rgbMax = rgbTable[ hue2 % 360 ];
00756 }
00757 
00768 QwtHueColorMap::QwtHueColorMap( QwtColorMap::Format format ):
00769     QwtColorMap( format )
00770 {
00771     d_data = new PrivateData;
00772 }
00773 
00775 QwtHueColorMap::~QwtHueColorMap()
00776 {
00777     delete d_data;
00778 }
00779 
00791 void QwtHueColorMap::setHueInterval( int hue1, int hue2 )
00792 {
00793     d_data->hue1 = qMax( hue1, 0 );
00794     d_data->hue2 = qMax( hue2, 0 );
00795 
00796     d_data->rgbMin = d_data->rgbTable[ hue1 % 360 ];
00797     d_data->rgbMax = d_data->rgbTable[ hue2 % 360 ];
00798 }
00799 
00809 void QwtHueColorMap::setSaturation( int saturation )
00810 {
00811     saturation = qBound( 0, saturation, 255 );
00812 
00813     if ( saturation != d_data->saturation )
00814     {
00815         d_data->saturation = saturation;
00816         d_data->updateTable();
00817     }
00818 }
00819 
00829 void QwtHueColorMap::setValue( int value )
00830 {
00831     value = qBound( 0, value, 255 );
00832 
00833     if ( value != d_data->value )
00834     {
00835         d_data->value = value;
00836         d_data->updateTable();
00837     }
00838 }
00839 
00850 void QwtHueColorMap::setAlpha( int alpha )
00851 {
00852     alpha = qBound( 0, alpha, 255 );
00853 
00854     if ( alpha != d_data->alpha )
00855     {
00856         d_data->alpha = alpha;
00857         d_data->updateTable();
00858     }
00859 }
00860 
00865 int QwtHueColorMap::hue1() const
00866 {
00867     return d_data->hue1;
00868 }
00869 
00874 int QwtHueColorMap::hue2() const
00875 {
00876     return d_data->hue2;
00877 }
00878 
00883 int QwtHueColorMap::saturation() const
00884 {
00885     return d_data->saturation;
00886 }
00887 
00892 int QwtHueColorMap::value() const
00893 {
00894     return d_data->value;
00895 }
00896 
00901 int QwtHueColorMap::alpha() const
00902 {
00903     return d_data->alpha;
00904 }
00905 
00914 QRgb QwtHueColorMap::rgb( const QwtInterval &interval, double value ) const
00915 {
00916     const double width = interval.width();
00917     if ( width <= 0 )
00918         return 0u;
00919 
00920     if ( value <= interval.minValue() )
00921         return d_data->rgbMin;
00922 
00923     if ( value >= interval.maxValue() )
00924         return d_data->rgbMax;
00925 
00926     const double ratio = ( value - interval.minValue() ) / width;
00927     
00928     int hue = d_data->hue1 + qRound( ratio * ( d_data->hue2 - d_data->hue1 ) );
00929     if ( hue >= 360 )
00930     {
00931         hue -= 360;
00932 
00933         if ( hue >= 360 )
00934             hue = hue % 360;
00935     }
00936 
00937     return d_data->rgbTable[hue];
00938 }
00939 
00940 class QwtSaturationValueColorMap::PrivateData
00941 {
00942 public:
00943     PrivateData():
00944         hue(0),
00945         sat1(255),
00946         sat2(255),
00947         value1(0),
00948         value2(255),
00949         alpha(255),
00950         tableType(Invalid)
00951     {
00952         updateTable();
00953     }
00954 
00955     void updateTable()
00956     {
00957         tableType = Invalid;
00958 
00959         if ( ( value1 == value2 ) && ( sat1 != sat2 ) )
00960         {
00961             rgbTable.resize( 256 );
00962 
00963             for ( int i = 0; i < 256; i++ )
00964                 rgbTable[i] = qwtHsvToRgb( hue, i, value1, alpha );
00965 
00966             tableType = Saturation;
00967         }
00968         else if ( ( value1 != value2 ) && ( sat1 == sat2 ) )
00969         {
00970             rgbTable.resize( 256 );
00971 
00972             for ( int i = 0; i < 256; i++ )
00973                 rgbTable[i] = qwtHsvToRgb( hue, sat1, i, alpha );
00974 
00975             tableType = Value;
00976         }
00977         else
00978         {
00979             rgbTable.resize( 256 * 256 );
00980 
00981             for ( int s = 0; s < 256; s++ )
00982             {
00983                 const int v0 = s * 256;
00984 
00985                 for ( int v = 0; v < 256; v++ )
00986                     rgbTable[v0 + v] = qwtHsvToRgb( hue, s, v, alpha );
00987             }
00988         }
00989     }
00990 
00991     int hue;
00992     int sat1, sat2;
00993     int value1, value2;
00994     int alpha;
00995 
00996     enum
00997     {
00998         Invalid,
00999         Value,
01000         Saturation
01001 
01002     } tableType;
01003 
01004     QVector<QRgb> rgbTable;
01005 };
01006 
01017 QwtSaturationValueColorMap::QwtSaturationValueColorMap()
01018 {
01019     d_data = new PrivateData;
01020 }
01021 
01023 QwtSaturationValueColorMap::~QwtSaturationValueColorMap()
01024 {
01025     delete d_data;
01026 }
01027 
01037 void QwtSaturationValueColorMap::setHue( int hue )
01038 {
01039     hue = hue % 360;
01040 
01041     if ( hue != d_data->hue )
01042     {
01043         d_data->hue = hue;
01044         d_data->updateTable();
01045     }
01046 }
01047 
01061 void QwtSaturationValueColorMap::setSaturationInterval( 
01062     int saturation1, int saturation2 )
01063 {
01064     saturation1 = qBound( 0, saturation1, 255 );
01065     saturation2 = qBound( 0, saturation2, 255 );
01066 
01067     if ( ( saturation1 != d_data->sat1 ) || ( saturation2 != d_data->sat2 ) )
01068     {
01069         d_data->sat1 = saturation1;
01070         d_data->sat2 = saturation2;
01071 
01072         d_data->updateTable();
01073     }
01074 }
01075 
01088 void QwtSaturationValueColorMap::setValueInterval( int value1, int value2 )
01089 {
01090     value1 = qBound( 0, value1, 255 );
01091     value2 = qBound( 0, value2, 255 );
01092 
01093     if ( ( value1 != d_data->value1 ) || ( value2 != d_data->value2 ) )
01094     {
01095         d_data->value1 = value1;
01096         d_data->value2 = value2;
01097     
01098         d_data->updateTable();
01099     }
01100 }
01101 
01112 void QwtSaturationValueColorMap::setAlpha( int alpha )
01113 {
01114     alpha = qBound( 0, alpha, 255 );
01115 
01116     if ( alpha != d_data->alpha )
01117     {
01118         d_data->alpha = alpha;
01119         d_data->updateTable();
01120     }
01121 }
01122 
01127 int QwtSaturationValueColorMap::hue() const
01128 {
01129     return d_data->hue;
01130 }
01131 
01136 int QwtSaturationValueColorMap::saturation1() const
01137 {
01138     return d_data->sat1;
01139 }
01140 
01145 int QwtSaturationValueColorMap::saturation2() const
01146 {
01147     return d_data->sat2;
01148 }
01149 
01154 int QwtSaturationValueColorMap::value1() const
01155 {
01156     return d_data->value1;
01157 }
01158 
01163 int QwtSaturationValueColorMap::value2() const
01164 {
01165     return d_data->value2;
01166 }
01167 
01172 int QwtSaturationValueColorMap::alpha() const
01173 {
01174     return d_data->alpha;
01175 }
01176 
01185 QRgb QwtSaturationValueColorMap::rgb( 
01186     const QwtInterval &interval, double value ) const
01187 {
01188     const double width = interval.width();
01189     if ( width <= 0 )
01190         return 0u;
01191 
01192     const QRgb *rgbTable = d_data->rgbTable.constData();
01193 
01194     switch( d_data->tableType )
01195     {
01196         case PrivateData::Saturation:
01197         {
01198             if ( value <= interval.minValue() )
01199                 return d_data->rgbTable[d_data->sat1];
01200 
01201             if ( value >= interval.maxValue() )
01202                 return d_data->rgbTable[d_data->sat2];
01203 
01204             const double ratio = ( value - interval.minValue() ) / width;
01205             const int sat = d_data->sat1
01206                 + qRound( ratio * ( d_data->sat2 - d_data->sat1 ) );
01207 
01208             return rgbTable[sat];
01209         }
01210         case PrivateData::Value:
01211         {
01212             if ( value <= interval.minValue() )
01213                 return d_data->rgbTable[d_data->value1];
01214 
01215             if ( value >= interval.maxValue() )
01216                 return d_data->rgbTable[d_data->value2];
01217 
01218             const double ratio = ( value - interval.minValue() ) / width;
01219             const int v = d_data->value1 +
01220                 qRound( ratio * ( d_data->value2 - d_data->value1 ) );
01221 
01222             return rgbTable[ v ];
01223         }
01224         default:
01225         {
01226             int s, v;
01227             if ( value <= interval.minValue() )
01228             {
01229                 s = d_data->sat1;
01230                 v = d_data->value1;
01231             }
01232             else if ( value >= interval.maxValue() )
01233             {
01234                 s = d_data->sat2;
01235                 v = d_data->value2;
01236             }
01237             else
01238             {
01239                 const double ratio = ( value - interval.minValue() ) / width;
01240 
01241                 v = d_data->value1 + qRound( ratio * ( d_data->value2 - d_data->value1 ) );
01242                 s = d_data->sat1 + qRound( ratio * ( d_data->sat2 - d_data->sat1 ) );
01243             }
01244 
01245             return rgbTable[ 256 * s + v ];
01246         }
01247     }
01248 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56