osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthSymbology/Color.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include <osgEarthSymbology/Color>
00020 #include <algorithm>
00021 #include <osg/Vec4ub>
00022 #include <sstream>
00023 #include <iomanip>
00024 
00025 using namespace osgEarth::Symbology;
00026 
00027 namespace
00028 {
00029     void rgb2hsv( osg::Vec4f& c )
00030     {
00031         float minval = std::min( c.r(), std::min( c.g(), c.b() ) );
00032         float maxval = std::max( c.r(), std::max( c.g(), c.b() ) );
00033         float delta = maxval - minval;
00034         float h = 0.0f, s = 0.0, v = maxval;
00035         if ( delta != 0.0f )
00036         {
00037             s = delta / maxval;
00038             float dr = (((maxval-c.r())/6.0f)+(delta/2.0f))/delta;
00039             float dg = (((maxval-c.g())/6.0f)+(delta/2.0f))/delta;
00040             float db = (((maxval-c.b())/6.0f)+(delta/2.0f))/delta;
00041             if ( c.r() == maxval ) h = db - dg;
00042             else if ( c.g() == maxval ) h = (1.0f/3.0f)+dr-db;
00043             else if ( c.b() == maxval ) h = (2.0f/3.0f)+dg-dr;
00044             if ( h < 0.0f ) h += 1.0f;
00045             if ( h > 1.0f ) h -= 1.0f;
00046         }
00047         c.set( h, s, v, c.a() );
00048     }
00049 
00050     void hsv2rgb( osg::Vec4f& c )
00051     {
00052         float h = c[0], s = c[1], v = c[2];
00053         if ( s == 0.0f ) {
00054             c.r() = c.g() = c.b() = 1.0f;
00055         }
00056         else {
00057             float vh = h*6.0f;
00058             float vi = floor(vh);
00059             float v1 = v * (1.0f - s);
00060             float v2 = v * (1.0f - s * (vh-vi));
00061             float v3 = v * (1.0f - s * (1.0f - (vh-vi)));
00062             float vr, vg, vb;
00063             if ( vi == 0.0f )      { vr = v,  vg = v3, vb = v1; }
00064             else if ( vi == 1.0f ) { vr = v2, vg = v,  vb = v1; }
00065             else if ( vi == 2.0f ) { vr = v1, vg = v,  vb = v3; }
00066             else if ( vi == 3.0f ) { vr = v1, vb = v2, vb = v; }
00067             else if ( vi == 4.0f ) { vr = v3, vg = v1, vb = v; }
00068             else                   { vr = v,  vg = v1, vb = v2; }
00069             c.set( vr, vg, vb, c.a() );
00070         }
00071     }
00072 }
00073 
00074 Color Color::White    ( 0xffffffff );
00075 Color Color::Silver   ( 0xc0c0c0ff );
00076 Color Color::Gray     ( 0x808080ff );
00077 Color Color::Black    ( 0x000000ff );
00078 Color Color::Red      ( 0xff0000ff );
00079 Color Color::Maroon   ( 0x800000ff );
00080 Color Color::Yellow   ( 0xffff00ff );
00081 Color Color::Olive    ( 0x808000ff );
00082 Color Color::Lime     ( 0x00ff00ff );
00083 Color Color::Green    ( 0x008000ff );
00084 Color Color::Aqua     ( 0x00ffffff );
00085 Color Color::Teal     ( 0x008080ff );
00086 Color Color::Blue     ( 0x0000ffff );
00087 Color Color::Navy     ( 0x000080ff );
00088 Color Color::Fuchsia  ( 0xff00ffff );
00089 Color Color::Purple   ( 0x800080ff );
00090 Color Color::Orange   ( 0xffa500ff );
00091 
00092 Color Color::DarkGray ( 0x404040ff );
00093 Color Color::Cyan     ( 0x00ffffff );
00094 
00095 Color::Color( unsigned rgba )
00096 {
00097     set(
00098         (float)(rgba>>24)/255.0f, 
00099         (float)((rgba&0xFF0000)>>16)/255.0f, 
00100         (float)((rgba&0xFF00)>>8)/255.0f,
00101         (float)(rgba&0xFF)/255.0f );
00102 }
00103 
00104 Color::Color( const Color& rhs, float a ) :
00105 osg::Vec4f( rhs )
00106 {
00107     (*this)[3] = a;
00108 }
00109 
00111 Color::Color( const std::string& html, Format format )
00112 {
00113     std::string t = html;
00114     std::transform( t.begin(), t.end(), t.begin(), ::tolower );
00115     osg::Vec4ub c(0,0,0,255);
00116     if ( t.length() >= 7 ) {
00117         c.r() |= t[1]<='9' ? (t[1]-'0')<<4 : (10+(t[1]-'a'))<<4;
00118         c.r() |= t[2]<='9' ? (t[2]-'0')    : (10+(t[2]-'a'));
00119         c.g() |= t[3]<='9' ? (t[3]-'0')<<4 : (10+(t[3]-'a'))<<4;
00120         c.g() |= t[4]<='9' ? (t[4]-'0')    : (10+(t[4]-'a'));
00121         c.b() |= t[5]<='9' ? (t[5]-'0')<<4 : (10+(t[5]-'a'))<<4;
00122         c.b() |= t[6]<='9' ? (t[6]-'0')    : (10+(t[6]-'a'));
00123         if ( t.length() == 9 ) {
00124             c.a() = 0;
00125             c.a() |= t[7]<='9' ? (t[7]-'0')<<4 : (10+(t[7]-'a'))<<4;
00126             c.a() |= t[8]<='9' ? (t[8]-'0')    : (10+(t[8]-'a'));
00127         }
00128     }
00129     float w = ((float)c.r())/255.0f;
00130     float x = ((float)c.g())/255.0f;
00131     float y = ((float)c.b())/255.0f;
00132     float z = ((float)c.a())/255.0f;
00133 
00134     if ( format == RGBA )
00135         set( w, x, y, z );
00136     else // ABGR
00137         set( z, y, x, w );
00138 }
00139 
00141 std::string
00142 Color::toHTML( Format format ) const
00143 {
00144     float w, x, y, z;
00145     if ( format == RGBA ) {
00146         w = r(), x = g(), y = b(), z = a();
00147     }
00148     else { // ABGR
00149         w = a(), x = b(), y = g(), z = r();
00150     }
00151 
00152     std::stringstream buf;
00153     buf << "#";
00154     buf << std::hex << std::setw(2) << std::setfill('0') << (int)(w*255.0f);
00155     buf << std::hex << std::setw(2) << std::setfill('0') << (int)(x*255.0f);
00156     buf << std::hex << std::setw(2) << std::setfill('0') << (int)(y*255.0f);
00157     buf << std::hex << std::setw(2) << std::setfill('0') << (int)(z*255.0f);
00158     std::string ssStr = buf.str();
00159     return ssStr;
00160 }
00161 
00162 Color
00163 Color::brightness( float perc ) const
00164 {
00165     Color c( *this );
00166     rgb2hsv( c );
00167     c.b() = osg::clampBetween( perc * c.b(), 0.0f, 1.0f );
00168     hsv2rgb( c );
00169     return c;
00170 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines