Index: trunk/BNC/qwt/qwt_color_map.cpp
===================================================================
--- trunk/BNC/qwt/qwt_color_map.cpp	(revision 4271)
+++ trunk/BNC/qwt/qwt_color_map.cpp	(revision 8127)
@@ -16,7 +16,8 @@
 {
 public:
-    ColorStops()
-    {
-        _stops.reserve( 256 );
+    ColorStops():
+        d_doAlpha( false )
+    {
+        d_stops.reserve( 256 );
     }
 
@@ -39,18 +40,48 @@
         ColorStop( double p, const QColor &c ):
             pos( p ),
-            rgb( c.rgb() )
+            rgb( c.rgba() )
         {
             r = qRed( rgb );
             g = qGreen( rgb );
             b = qBlue( rgb );
+            a = qAlpha( rgb );
+
+            /* 
+                when mapping a value to rgb we will have to calcualate: 
+                   - const int v = int( ( s1.v0 + ratio * s1.vStep ) + 0.5 );
+
+                Thus adding 0.5 ( for rounding ) can be done in advance
+             */
+            r0 = r + 0.5;
+            g0 = g + 0.5;
+            b0 = b + 0.5;
+            a0 = a + 0.5;
+
+            rStep = gStep = bStep = aStep = 0.0;
+            posStep = 0.0;
+        }
+
+        void updateSteps( const ColorStop &nextStop )
+        {
+            rStep = nextStop.r - r;
+            gStep = nextStop.g - g;
+            bStep = nextStop.b - b;
+            aStep = nextStop.a - a;
+            posStep = nextStop.pos - pos;
         }
 
         double pos;
         QRgb rgb;
-        int r, g, b;
+        int r, g, b, a;
+
+        // precalculated values
+        double rStep, gStep, bStep, aStep;
+        double r0, g0, b0, a0;
+        double posStep;
     };
 
     inline int findUpper( double pos ) const;
-    QVector<ColorStop> _stops;
+    QVector<ColorStop> d_stops;
+    bool d_doAlpha;
 };
 
@@ -64,29 +95,37 @@
 
     int index;
-    if ( _stops.size() == 0 )
+    if ( d_stops.size() == 0 )
     {
         index = 0;
-        _stops.resize( 1 );
+        d_stops.resize( 1 );
     }
     else
     {
         index = findUpper( pos );
-        if ( index == _stops.size() ||
-                qAbs( _stops[index].pos - pos ) >= 0.001 )
-        {
-            _stops.resize( _stops.size() + 1 );
-            for ( int i = _stops.size() - 1; i > index; i-- )
-                _stops[i] = _stops[i-1];
-        }
-    }
-
-    _stops[index] = ColorStop( pos, color );
+        if ( index == d_stops.size() ||
+                qAbs( d_stops[index].pos - pos ) >= 0.001 )
+        {
+            d_stops.resize( d_stops.size() + 1 );
+            for ( int i = d_stops.size() - 1; i > index; i-- )
+                d_stops[i] = d_stops[i-1];
+        }
+    }
+
+    d_stops[index] = ColorStop( pos, color );
+    if ( color.alpha() != 255 )
+        d_doAlpha = true;
+
+    if ( index > 0 )
+        d_stops[index-1].updateSteps( d_stops[index] );
+
+    if ( index < d_stops.size() - 1 )
+        d_stops[index].updateSteps( d_stops[index+1] );
 }
 
 inline QVector<double> QwtLinearColorMap::ColorStops::stops() const
 {
-    QVector<double> positions( _stops.size() );
-    for ( int i = 0; i < _stops.size(); i++ )
-        positions[i] = _stops[i].pos;
+    QVector<double> positions( d_stops.size() );
+    for ( int i = 0; i < d_stops.size(); i++ )
+        positions[i] = d_stops[i].pos;
     return positions;
 }
@@ -95,7 +134,7 @@
 {
     int index = 0;
-    int n = _stops.size();
-
-    const ColorStop *stops = _stops.data();
+    int n = d_stops.size();
+
+    const ColorStop *stops = d_stops.data();
 
     while ( n > 0 )
@@ -120,25 +159,39 @@
 {
     if ( pos <= 0.0 )
-        return _stops[0].rgb;
+        return d_stops[0].rgb;
     if ( pos >= 1.0 )
-        return _stops[ _stops.size() - 1 ].rgb;
+        return d_stops[ d_stops.size() - 1 ].rgb;
 
     const int index = findUpper( pos );
     if ( mode == FixedColors )
     {
-        return _stops[index-1].rgb;
+        return d_stops[index-1].rgb;
     }
     else
     {
-        const ColorStop &s1 = _stops[index-1];
-        const ColorStop &s2 = _stops[index];
-
-        const double ratio = ( pos - s1.pos ) / ( s2.pos - s1.pos );
-
-        const int r = s1.r + qRound( ratio * ( s2.r - s1.r ) );
-        const int g = s1.g + qRound( ratio * ( s2.g - s1.g ) );
-        const int b = s1.b + qRound( ratio * ( s2.b - s1.b ) );
-
-        return qRgb( r, g, b );
+        const ColorStop &s1 = d_stops[index-1];
+
+        const double ratio = ( pos - s1.pos ) / ( s1.posStep );
+
+        const int r = int( s1.r0 + ratio * s1.rStep );
+        const int g = int( s1.g0 + ratio * s1.gStep );
+        const int b = int( s1.b0 + ratio * s1.bStep );
+
+        if ( d_doAlpha )
+        {
+            if ( s1.aStep )
+            {
+                const int a = int( s1.a0 + ratio * s1.aStep );
+                return qRgba( r, g, b, a );
+            }
+            else
+            {
+                return qRgba( r, g, b, s1.a );
+            }
+        }
+        else
+        {
+            return qRgb( r, g, b );
+        }
     }
 }
@@ -205,5 +258,5 @@
    \param color1 Color used for the minimum value of the value interval
    \param color2 Color used for the maximum value of the value interval
-   \param format Preferred format of the coor map
+   \param format Preferred format for the color map
 */
 QwtLinearColorMap::QwtLinearColorMap( const QColor &color1,
@@ -280,5 +333,5 @@
 
 /*!
-   Return all positions of color stops in increasing order
+   \return Positions of color stops in increasing order
 */
 QVector<double> QwtLinearColorMap::colorStops() const
@@ -306,8 +359,10 @@
 
 /*!
-  Map a value of a given interval into a rgb value
+  Map a value of a given interval into a RGB value
 
   \param interval Range for all values
-  \param value Value to map into a rgb value
+  \param value Value to map into a RGB value
+
+  \return RGB value for value
 */
 QRgb QwtLinearColorMap::rgb(
@@ -315,20 +370,21 @@
 {
     if ( qIsNaN(value) )
-        return qRgba(0, 0, 0, 0);
+        return 0u;
 
     const double width = interval.width();
-
-    double ratio = 0.0;
-    if ( width > 0.0 )
-        ratio = ( value - interval.minValue() ) / width;
-
+    if ( width <= 0.0 )
+        return 0u;
+
+    const double ratio = ( value - interval.minValue() ) / width;
     return d_data->colorStops.rgb( d_data->mode, ratio );
 }
 
 /*!
-  Map a value of a given interval into a color index, between 0 and 255
+  \brief Map a value of a given interval into a color index
 
   \param interval Range for all values
   \param value Value to map into a color index
+
+  \return Index, between 0 and 255
 */
 unsigned char QwtLinearColorMap::colorIndex(
@@ -341,5 +397,5 @@
 
     if ( value >= interval.maxValue() )
-        return ( unsigned char )255;
+        return 255;
 
     const double ratio = ( value - interval.minValue() ) / width;
@@ -347,7 +403,7 @@
     unsigned char index;
     if ( d_data->mode == FixedColors )
-        index = ( unsigned char )( ratio * 255 ); // always floor
+        index = static_cast<unsigned char>( ratio * 255 ); // always floor
     else
-        index = ( unsigned char )qRound( ratio * 255 );
+        index = static_cast<unsigned char>( ratio * 255 + 0.5 );
 
     return index;
@@ -359,4 +415,5 @@
     QColor color;
     QRgb rgb;
+    QRgb rgbMax;
 };
 
@@ -370,24 +427,24 @@
 {
     d_data = new PrivateData;
+    setColor( color );
+}
+
+//! Destructor
+QwtAlphaColorMap::~QwtAlphaColorMap()
+{
+    delete d_data;
+}
+
+/*!
+   Set the color
+
+   \param color Color
+   \sa color()
+*/
+void QwtAlphaColorMap::setColor( const QColor &color )
+{
     d_data->color = color;
     d_data->rgb = color.rgb() & qRgba( 255, 255, 255, 0 );
-}
-
-//! Destructor
-QwtAlphaColorMap::~QwtAlphaColorMap()
-{
-    delete d_data;
-}
-
-/*!
-   Set the color
-
-   \param color Color
-   \sa color()
-*/
-void QwtAlphaColorMap::setColor( const QColor &color )
-{
-    d_data->color = color;
-    d_data->rgb = color.rgb();
+    d_data->rgbMax = d_data->rgb | ( 255 << 24 );
 }
 
@@ -407,22 +464,24 @@
 
   \param interval Range for all values
-  \param value Value to map into a rgb value
-  \return rgb value, with an alpha value
+  \param value Value to map into a RGB value
+  \return RGB value, with an alpha value
 */
 QRgb QwtAlphaColorMap::rgb( const QwtInterval &interval, double value ) const
 {
+    if ( qIsNaN(value) )
+        return 0u;
+
     const double width = interval.width();
-    if ( !qIsNaN(value) && width >= 0.0 )
-    {
-        const double ratio = ( value - interval.minValue() ) / width;
-        int alpha = qRound( 255 * ratio );
-        if ( alpha < 0 )
-            alpha = 0;
-        if ( alpha > 255 )
-            alpha = 255;
-
-        return d_data->rgb | ( alpha << 24 );
-    }
-    return d_data->rgb;
+    if ( width <= 0.0 )
+        return 0u;
+
+    if ( value <= interval.minValue() )
+        return d_data->rgb;
+
+    if ( value >= interval.maxValue() )
+        return d_data->rgbMax;
+
+    const double ratio = ( value - interval.minValue() ) / width;
+    return d_data->rgb | ( qRound( 255 * ratio ) << 24 );
 }
 
