xref: /AOO41X/main/slideshow/source/engine/color.cxx (revision 70f497fb4451dd853e622598505702a3cb5381a8)
1*70f497fbSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*70f497fbSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*70f497fbSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*70f497fbSAndrew Rist  * distributed with this work for additional information
6*70f497fbSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*70f497fbSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*70f497fbSAndrew Rist  * "License"); you may not use this file except in compliance
9*70f497fbSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*70f497fbSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*70f497fbSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*70f497fbSAndrew Rist  * software distributed under the License is distributed on an
15*70f497fbSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*70f497fbSAndrew Rist  * KIND, either express or implied.  See the License for the
17*70f497fbSAndrew Rist  * specific language governing permissions and limitations
18*70f497fbSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*70f497fbSAndrew Rist  *************************************************************/
21*70f497fbSAndrew Rist 
22*70f497fbSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <hslcolor.hxx>
28cdf0e10cSrcweir #include <rgbcolor.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <cmath> // for fmod
33cdf0e10cSrcweir #include <algorithm>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir 
36cdf0e10cSrcweir namespace slideshow
37cdf0e10cSrcweir {
38cdf0e10cSrcweir     namespace internal
39cdf0e10cSrcweir     {
40cdf0e10cSrcweir         namespace
41cdf0e10cSrcweir         {
42cdf0e10cSrcweir             // helper functions
43cdf0e10cSrcweir             // ================
44cdf0e10cSrcweir 
getMagic(double nLuminance,double nSaturation)45cdf0e10cSrcweir             double getMagic( double nLuminance, double nSaturation )
46cdf0e10cSrcweir             {
47cdf0e10cSrcweir                 if( nLuminance <= 0.5 )
48cdf0e10cSrcweir                     return nLuminance*(1.0 + nSaturation);
49cdf0e10cSrcweir                 else
50cdf0e10cSrcweir                     return nLuminance + nSaturation - nLuminance*nSaturation;
51cdf0e10cSrcweir             }
52cdf0e10cSrcweir 
rgb2hsl(double nRed,double nGreen,double nBlue)53cdf0e10cSrcweir             HSLColor::HSLTriple rgb2hsl( double nRed, double nGreen, double nBlue )
54cdf0e10cSrcweir             {
55cdf0e10cSrcweir                 // r,g,b in [0,1], h in [0,360] and s,l in [0,1]
56cdf0e10cSrcweir                 HSLColor::HSLTriple aRes;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir                 const double nMax( ::std::max(nRed,::std::max(nGreen, nBlue)) );
59cdf0e10cSrcweir                 const double nMin( ::std::min(nRed,::std::min(nGreen, nBlue)) );
60cdf0e10cSrcweir 
61cdf0e10cSrcweir                 const double nDelta( nMax - nMin );
62cdf0e10cSrcweir 
63cdf0e10cSrcweir                 aRes.mnLuminance = (nMax + nMin) / 2.0;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir                 if( ::basegfx::fTools::equalZero( nDelta ) )
66cdf0e10cSrcweir                 {
67cdf0e10cSrcweir                     aRes.mnSaturation = 0.0;
68cdf0e10cSrcweir 
69cdf0e10cSrcweir                     // hue undefined (achromatic case)
70cdf0e10cSrcweir                     aRes.mnHue = 0.0;
71cdf0e10cSrcweir                 }
72cdf0e10cSrcweir                 else
73cdf0e10cSrcweir                 {
74cdf0e10cSrcweir                     aRes.mnSaturation = aRes.mnLuminance > 0.5 ?
75cdf0e10cSrcweir                         nDelta/(2.0-nMax-nMin) :
76cdf0e10cSrcweir                         nDelta/(nMax + nMin);
77cdf0e10cSrcweir 
78cdf0e10cSrcweir                     if( nRed == nMax )
79cdf0e10cSrcweir                         aRes.mnHue = (nGreen - nBlue)/nDelta;
80cdf0e10cSrcweir                     else if( nGreen == nMax )
81cdf0e10cSrcweir                         aRes.mnHue = 2.0 + (nBlue - nRed)/nDelta;
82cdf0e10cSrcweir                     else if( nBlue == nMax )
83cdf0e10cSrcweir                         aRes.mnHue = 4.0 + (nRed - nGreen)/nDelta;
84cdf0e10cSrcweir 
85cdf0e10cSrcweir                     aRes.mnHue *= 60.0;
86cdf0e10cSrcweir 
87cdf0e10cSrcweir                     if( aRes.mnHue < 0.0 )
88cdf0e10cSrcweir                         aRes.mnHue += 360.0;
89cdf0e10cSrcweir                 }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir                 return aRes;
92cdf0e10cSrcweir             }
93cdf0e10cSrcweir 
hsl2rgbHelper(double nValue1,double nValue2,double nHue)94cdf0e10cSrcweir             double hsl2rgbHelper( double nValue1, double nValue2, double nHue )
95cdf0e10cSrcweir             {
96cdf0e10cSrcweir                 // clamp hue to [0,360]
97cdf0e10cSrcweir                 nHue = fmod( nHue, 360.0 );
98cdf0e10cSrcweir 
99cdf0e10cSrcweir                 // cope with wrap-arounds
100cdf0e10cSrcweir                 if( nHue < 0.0 )
101cdf0e10cSrcweir                     nHue += 360.0;
102cdf0e10cSrcweir 
103cdf0e10cSrcweir                 if( nHue < 60.0 )
104cdf0e10cSrcweir                     return nValue1 + (nValue2 - nValue1)*nHue/60.0;
105cdf0e10cSrcweir                 else if( nHue < 180.0 )
106cdf0e10cSrcweir                     return nValue2;
107cdf0e10cSrcweir                 else if( nHue < 240.0 )
108cdf0e10cSrcweir                     return nValue1 + (nValue2 - nValue1)*(240.0 - nHue)/60.0;
109cdf0e10cSrcweir                 else
110cdf0e10cSrcweir                     return nValue1;
111cdf0e10cSrcweir             }
112cdf0e10cSrcweir 
hsl2rgb(double nHue,double nSaturation,double nLuminance)113cdf0e10cSrcweir             RGBColor::RGBTriple hsl2rgb( double nHue, double nSaturation, double nLuminance )
114cdf0e10cSrcweir             {
115cdf0e10cSrcweir                 if( ::basegfx::fTools::equalZero( nSaturation ) )
116cdf0e10cSrcweir                     return RGBColor::RGBTriple(0.0, 0.0, nLuminance );
117cdf0e10cSrcweir 
118cdf0e10cSrcweir                 const double nVal1( getMagic(nLuminance, nSaturation) );
119cdf0e10cSrcweir                 const double nVal2( 2.0*nLuminance - nVal1 );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir                 RGBColor::RGBTriple aRes;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir                 aRes.mnRed = hsl2rgbHelper( nVal2,
124cdf0e10cSrcweir                                             nVal1,
125cdf0e10cSrcweir                                             nHue + 120.0 );
126cdf0e10cSrcweir                 aRes.mnGreen = hsl2rgbHelper( nVal2,
127cdf0e10cSrcweir                                               nVal1,
128cdf0e10cSrcweir                                               nHue );
129cdf0e10cSrcweir                 aRes.mnBlue = hsl2rgbHelper( nVal2,
130cdf0e10cSrcweir                                              nVal1,
131cdf0e10cSrcweir                                              nHue - 120.0 );
132cdf0e10cSrcweir 
133cdf0e10cSrcweir                 return aRes;
134cdf0e10cSrcweir             }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir             /// Truncate range of value to [0,1]
truncateRangeStd(double nVal)137cdf0e10cSrcweir             double truncateRangeStd( double nVal )
138cdf0e10cSrcweir             {
139cdf0e10cSrcweir                 return ::std::max( 0.0,
140cdf0e10cSrcweir                                    ::std::min( 1.0,
141cdf0e10cSrcweir                                                nVal ) );
142cdf0e10cSrcweir             }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir             /// Truncate range of value to [0,360]
truncateRangeHue(double nVal)145cdf0e10cSrcweir             double truncateRangeHue( double nVal )
146cdf0e10cSrcweir             {
147cdf0e10cSrcweir                 return ::std::max( 0.0,
148cdf0e10cSrcweir                                    ::std::min( 360.0,
149cdf0e10cSrcweir                                                nVal ) );
150cdf0e10cSrcweir             }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir             /// convert RGB color to sal_uInt8, truncate range appropriately before
colorToInt(double nCol)153cdf0e10cSrcweir             sal_uInt8 colorToInt( double nCol )
154cdf0e10cSrcweir             {
155cdf0e10cSrcweir                 return static_cast< sal_uInt8 >(
156cdf0e10cSrcweir                     ::basegfx::fround( truncateRangeStd( nCol ) * 255.0 ) );
157cdf0e10cSrcweir             }
158cdf0e10cSrcweir         }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 
162cdf0e10cSrcweir         // HSLColor
163cdf0e10cSrcweir         // ===============================================
164cdf0e10cSrcweir 
HSLTriple()165cdf0e10cSrcweir         HSLColor::HSLTriple::HSLTriple() :
166cdf0e10cSrcweir             mnHue(),
167cdf0e10cSrcweir             mnSaturation(),
168cdf0e10cSrcweir             mnLuminance()
169cdf0e10cSrcweir         {
170cdf0e10cSrcweir         }
171cdf0e10cSrcweir 
HSLTriple(double nHue,double nSaturation,double nLuminance)172cdf0e10cSrcweir         HSLColor::HSLTriple::HSLTriple( double nHue, double nSaturation, double nLuminance ) :
173cdf0e10cSrcweir             mnHue( nHue ),
174cdf0e10cSrcweir             mnSaturation( nSaturation ),
175cdf0e10cSrcweir             mnLuminance( nLuminance )
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir         }
178cdf0e10cSrcweir 
HSLColor()179cdf0e10cSrcweir         HSLColor::HSLColor() :
180cdf0e10cSrcweir             maHSLTriple( 0.0, 0.0, 0.0 ),
181cdf0e10cSrcweir             mnMagicValue( getMagic( maHSLTriple.mnLuminance,
182cdf0e10cSrcweir                                     maHSLTriple.mnSaturation ) )
183cdf0e10cSrcweir         {
184cdf0e10cSrcweir         }
185cdf0e10cSrcweir 
HSLColor(::cppcanvas::Color::IntSRGBA nRGBColor)186cdf0e10cSrcweir         HSLColor::HSLColor( ::cppcanvas::Color::IntSRGBA nRGBColor ) :
187cdf0e10cSrcweir             maHSLTriple( rgb2hsl( ::cppcanvas::getRed( nRGBColor ) / 255.0,
188cdf0e10cSrcweir                                   ::cppcanvas::getGreen( nRGBColor ) / 255.0,
189cdf0e10cSrcweir                                   ::cppcanvas::getBlue( nRGBColor ) / 255.0 ) ),
190cdf0e10cSrcweir             mnMagicValue( getMagic( maHSLTriple.mnLuminance,
191cdf0e10cSrcweir                                     maHSLTriple.mnSaturation ) )
192cdf0e10cSrcweir         {
193cdf0e10cSrcweir         }
194cdf0e10cSrcweir 
HSLColor(double nHue,double nSaturation,double nLuminance)195cdf0e10cSrcweir         HSLColor::HSLColor( double nHue, double nSaturation, double nLuminance ) :
196cdf0e10cSrcweir             maHSLTriple( nHue, nSaturation, nLuminance ),
197cdf0e10cSrcweir             mnMagicValue( getMagic( maHSLTriple.mnLuminance,
198cdf0e10cSrcweir                                     maHSLTriple.mnSaturation ) )
199cdf0e10cSrcweir         {
200cdf0e10cSrcweir         }
201cdf0e10cSrcweir 
HSLColor(const RGBColor & rColor)202cdf0e10cSrcweir         HSLColor::HSLColor( const RGBColor& rColor ) :
203cdf0e10cSrcweir             maHSLTriple( rgb2hsl( truncateRangeStd( rColor.getRed() ),
204cdf0e10cSrcweir                                   truncateRangeStd( rColor.getGreen() ),
205cdf0e10cSrcweir                                   truncateRangeStd( rColor.getBlue() ) ) ),
206cdf0e10cSrcweir             mnMagicValue( getMagic( maHSLTriple.mnLuminance,
207cdf0e10cSrcweir                                     maHSLTriple.mnSaturation ) )
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir         }
210cdf0e10cSrcweir 
getHue() const211cdf0e10cSrcweir         double HSLColor::getHue() const
212cdf0e10cSrcweir         {
213cdf0e10cSrcweir             return maHSLTriple.mnHue;
214cdf0e10cSrcweir         }
215cdf0e10cSrcweir 
getSaturation() const216cdf0e10cSrcweir         double HSLColor::getSaturation() const
217cdf0e10cSrcweir         {
218cdf0e10cSrcweir             return maHSLTriple.mnSaturation;
219cdf0e10cSrcweir         }
220cdf0e10cSrcweir 
getLuminance() const221cdf0e10cSrcweir         double HSLColor::getLuminance() const
222cdf0e10cSrcweir         {
223cdf0e10cSrcweir             return maHSLTriple.mnLuminance;
224cdf0e10cSrcweir         }
225cdf0e10cSrcweir 
getRed() const226cdf0e10cSrcweir         double HSLColor::getRed() const
227cdf0e10cSrcweir         {
228cdf0e10cSrcweir             if( ::basegfx::fTools::equalZero( getSaturation() ) )
229cdf0e10cSrcweir                 return getLuminance();
230cdf0e10cSrcweir 
231cdf0e10cSrcweir             return hsl2rgbHelper( 2.0*getLuminance() - mnMagicValue,
232cdf0e10cSrcweir                                   mnMagicValue,
233cdf0e10cSrcweir                                   getHue() + 120.0 );
234cdf0e10cSrcweir         }
235cdf0e10cSrcweir 
getGreen() const236cdf0e10cSrcweir         double HSLColor::getGreen() const
237cdf0e10cSrcweir         {
238cdf0e10cSrcweir             if( ::basegfx::fTools::equalZero( getSaturation() ) )
239cdf0e10cSrcweir                 return getLuminance();
240cdf0e10cSrcweir 
241cdf0e10cSrcweir             return hsl2rgbHelper( 2.0*getLuminance() - mnMagicValue,
242cdf0e10cSrcweir                                   mnMagicValue,
243cdf0e10cSrcweir                                   getHue() );
244cdf0e10cSrcweir         }
245cdf0e10cSrcweir 
getBlue() const246cdf0e10cSrcweir         double HSLColor::getBlue() const
247cdf0e10cSrcweir         {
248cdf0e10cSrcweir             if( ::basegfx::fTools::equalZero( getSaturation() ) )
249cdf0e10cSrcweir                 return getLuminance();
250cdf0e10cSrcweir 
251cdf0e10cSrcweir             return hsl2rgbHelper( 2.0*getLuminance() - mnMagicValue,
252cdf0e10cSrcweir                                   mnMagicValue,
253cdf0e10cSrcweir                                   getHue() - 120.0 );
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir 
getRGBColor() const256cdf0e10cSrcweir         RGBColor HSLColor::getRGBColor() const
257cdf0e10cSrcweir         {
258cdf0e10cSrcweir             RGBColor::RGBTriple aColor( hsl2rgb( getHue(),
259cdf0e10cSrcweir                                                  getSaturation(),
260cdf0e10cSrcweir                                                  getLuminance() ) );
261cdf0e10cSrcweir             return RGBColor( aColor.mnRed, aColor.mnGreen, aColor.mnBlue );
262cdf0e10cSrcweir         }
263cdf0e10cSrcweir 
RGBColor(const RGBColor & rLHS)264cdf0e10cSrcweir         RGBColor::RGBColor(const RGBColor& rLHS)
265cdf0e10cSrcweir         {
266cdf0e10cSrcweir             maRGBTriple.mnRed = rLHS.getRed();
267cdf0e10cSrcweir             maRGBTriple.mnGreen = rLHS.getGreen();
268cdf0e10cSrcweir             maRGBTriple.mnBlue = rLHS.getBlue();
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir 
operator =(const RGBColor & rLHS)271cdf0e10cSrcweir         RGBColor& RGBColor::operator=( const RGBColor& rLHS ){
272cdf0e10cSrcweir 
273cdf0e10cSrcweir             maRGBTriple.mnRed = rLHS.getRed();
274cdf0e10cSrcweir             maRGBTriple.mnGreen = rLHS.getGreen();
275cdf0e10cSrcweir             maRGBTriple.mnBlue = rLHS.getBlue();
276cdf0e10cSrcweir             return *this;
277cdf0e10cSrcweir         }
278cdf0e10cSrcweir 
operator +(const HSLColor & rLHS,const HSLColor & rRHS)279cdf0e10cSrcweir         HSLColor operator+( const HSLColor& rLHS, const HSLColor& rRHS )
280cdf0e10cSrcweir         {
281cdf0e10cSrcweir             return HSLColor( rLHS.getHue() + rRHS.getHue(),
282cdf0e10cSrcweir                              rLHS.getSaturation() + rRHS.getSaturation(),
283cdf0e10cSrcweir                              rLHS.getLuminance() + rRHS.getLuminance() );
284cdf0e10cSrcweir         }
285cdf0e10cSrcweir 
operator *(const HSLColor & rLHS,const HSLColor & rRHS)286cdf0e10cSrcweir         HSLColor operator*( const HSLColor& rLHS, const HSLColor& rRHS )
287cdf0e10cSrcweir         {
288cdf0e10cSrcweir             return HSLColor( rLHS.getHue() * rRHS.getHue(),
289cdf0e10cSrcweir                              rLHS.getSaturation() * rRHS.getSaturation(),
290cdf0e10cSrcweir                              rLHS.getLuminance() * rRHS.getLuminance() );
291cdf0e10cSrcweir         }
292cdf0e10cSrcweir 
operator *(double nFactor,const HSLColor & rRHS)293cdf0e10cSrcweir         HSLColor operator*( double nFactor, const HSLColor& rRHS )
294cdf0e10cSrcweir         {
295cdf0e10cSrcweir             return HSLColor( nFactor * rRHS.getHue(),
296cdf0e10cSrcweir                              nFactor * rRHS.getSaturation(),
297cdf0e10cSrcweir                              nFactor * rRHS.getLuminance() );
298cdf0e10cSrcweir         }
299cdf0e10cSrcweir 
interpolate(const HSLColor & rFrom,const HSLColor & rTo,double t,bool bCCW)300cdf0e10cSrcweir         HSLColor interpolate( const HSLColor& rFrom, const HSLColor& rTo, double t, bool bCCW )
301cdf0e10cSrcweir         {
302cdf0e10cSrcweir             const double nFromHue( rFrom.getHue() );
303cdf0e10cSrcweir             const double nToHue	 ( rTo.getHue()   );
304cdf0e10cSrcweir 
305cdf0e10cSrcweir             double nHue=0.0;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir             if( nFromHue <= nToHue && !bCCW )
308cdf0e10cSrcweir             {
309cdf0e10cSrcweir                 // interpolate hue clockwise. That is, hue starts at
310cdf0e10cSrcweir                 // high values and ends at low ones. Therefore, we
311cdf0e10cSrcweir                 // must 'cross' the 360 degrees and start at low
312cdf0e10cSrcweir                 // values again (imagine the hues to lie on the
313cdf0e10cSrcweir                 // circle, where values above 360 degrees are mapped
314cdf0e10cSrcweir                 // back to [0,360)).
315cdf0e10cSrcweir                 nHue = (1.0-t)*(nFromHue + 360.0) + t*nToHue;
316cdf0e10cSrcweir             }
317cdf0e10cSrcweir             else if( nFromHue > nToHue && bCCW )
318cdf0e10cSrcweir             {
319cdf0e10cSrcweir                 // interpolate hue counter-clockwise. That is, hue
320cdf0e10cSrcweir                 // starts at high values and ends at low
321cdf0e10cSrcweir                 // ones. Therefore, we must 'cross' the 360 degrees
322cdf0e10cSrcweir                 // and start at low values again (imagine the hues to
323cdf0e10cSrcweir                 // lie on the circle, where values above 360 degrees
324cdf0e10cSrcweir                 // are mapped back to [0,360)).
325cdf0e10cSrcweir                 nHue = (1.0-t)*nFromHue + t*(nToHue + 360.0);
326cdf0e10cSrcweir             }
327cdf0e10cSrcweir             else
328cdf0e10cSrcweir             {
329cdf0e10cSrcweir                 // interpolate hue counter-clockwise. That is, hue
330cdf0e10cSrcweir                 // starts at low values and ends at high ones (imagine
331cdf0e10cSrcweir                 // the hue value as degrees on a circle, with
332cdf0e10cSrcweir                 // increasing values going counter-clockwise)
333cdf0e10cSrcweir                 nHue = (1.0-t)*nFromHue + t*nToHue;
334cdf0e10cSrcweir             }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir             return HSLColor( nHue,
337cdf0e10cSrcweir                              (1.0-t)*rFrom.getSaturation() + t*rTo.getSaturation(),
338cdf0e10cSrcweir                              (1.0-t)*rFrom.getLuminance() + t*rTo.getLuminance() );
339cdf0e10cSrcweir         }
340cdf0e10cSrcweir 
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 
343cdf0e10cSrcweir         // RGBColor
344cdf0e10cSrcweir         // ===============================================
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 
RGBTriple()347cdf0e10cSrcweir         RGBColor::RGBTriple::RGBTriple() :
348cdf0e10cSrcweir             mnRed(),
349cdf0e10cSrcweir             mnGreen(),
350cdf0e10cSrcweir             mnBlue()
351cdf0e10cSrcweir         {
352cdf0e10cSrcweir         }
353cdf0e10cSrcweir 
RGBTriple(double nRed,double nGreen,double nBlue)354cdf0e10cSrcweir         RGBColor::RGBTriple::RGBTriple( double nRed, double nGreen, double nBlue ) :
355cdf0e10cSrcweir             mnRed( nRed ),
356cdf0e10cSrcweir             mnGreen( nGreen ),
357cdf0e10cSrcweir             mnBlue( nBlue )
358cdf0e10cSrcweir         {
359cdf0e10cSrcweir         }
360cdf0e10cSrcweir 
RGBColor()361cdf0e10cSrcweir         RGBColor::RGBColor() :
362cdf0e10cSrcweir             maRGBTriple( 0.0, 0.0, 0.0 )
363cdf0e10cSrcweir         {
364cdf0e10cSrcweir         }
365cdf0e10cSrcweir 
RGBColor(::cppcanvas::Color::IntSRGBA nRGBColor)366cdf0e10cSrcweir         RGBColor::RGBColor( ::cppcanvas::Color::IntSRGBA nRGBColor ) :
367cdf0e10cSrcweir             maRGBTriple( ::cppcanvas::getRed( nRGBColor ) / 255.0,
368cdf0e10cSrcweir                          ::cppcanvas::getGreen( nRGBColor ) / 255.0,
369cdf0e10cSrcweir                          ::cppcanvas::getBlue( nRGBColor ) / 255.0 )
370cdf0e10cSrcweir         {
371cdf0e10cSrcweir         }
372cdf0e10cSrcweir 
RGBColor(double nRed,double nGreen,double nBlue)373cdf0e10cSrcweir         RGBColor::RGBColor( double nRed, double nGreen, double nBlue ) :
374cdf0e10cSrcweir             maRGBTriple( nRed, nGreen, nBlue )
375cdf0e10cSrcweir         {
376cdf0e10cSrcweir         }
377cdf0e10cSrcweir 
RGBColor(const HSLColor & rColor)378cdf0e10cSrcweir         RGBColor::RGBColor( const HSLColor& rColor ) :
379cdf0e10cSrcweir             maRGBTriple( hsl2rgb( truncateRangeHue( rColor.getHue() ),
380cdf0e10cSrcweir                                   truncateRangeStd( rColor.getSaturation() ),
381cdf0e10cSrcweir                                   truncateRangeStd( rColor.getLuminance() ) ) )
382cdf0e10cSrcweir         {
383cdf0e10cSrcweir         }
384cdf0e10cSrcweir 
getHue() const385cdf0e10cSrcweir         double RGBColor::getHue() const
386cdf0e10cSrcweir         {
387cdf0e10cSrcweir             return rgb2hsl( getRed(),
388cdf0e10cSrcweir                             getGreen(),
389cdf0e10cSrcweir                             getBlue() ).mnHue;
390cdf0e10cSrcweir         }
391cdf0e10cSrcweir 
getSaturation() const392cdf0e10cSrcweir         double RGBColor::getSaturation() const
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             return rgb2hsl( getRed(),
395cdf0e10cSrcweir                             getGreen(),
396cdf0e10cSrcweir                             getBlue() ).mnSaturation;
397cdf0e10cSrcweir         }
398cdf0e10cSrcweir 
getLuminance() const399cdf0e10cSrcweir         double RGBColor::getLuminance() const
400cdf0e10cSrcweir         {
401cdf0e10cSrcweir             return rgb2hsl( getRed(),
402cdf0e10cSrcweir                             getGreen(),
403cdf0e10cSrcweir                             getBlue() ).mnLuminance;
404cdf0e10cSrcweir         }
405cdf0e10cSrcweir 
getRed() const406cdf0e10cSrcweir         double RGBColor::getRed() const
407cdf0e10cSrcweir         {
408cdf0e10cSrcweir             return maRGBTriple.mnRed;
409cdf0e10cSrcweir         }
410cdf0e10cSrcweir 
getGreen() const411cdf0e10cSrcweir         double RGBColor::getGreen() const
412cdf0e10cSrcweir         {
413cdf0e10cSrcweir             return maRGBTriple.mnGreen;
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir 
getBlue() const416cdf0e10cSrcweir         double RGBColor::getBlue() const
417cdf0e10cSrcweir         {
418cdf0e10cSrcweir             return maRGBTriple.mnBlue;
419cdf0e10cSrcweir         }
420cdf0e10cSrcweir 
getHSLColor() const421cdf0e10cSrcweir         HSLColor RGBColor::getHSLColor() const
422cdf0e10cSrcweir         {
423cdf0e10cSrcweir             HSLColor::HSLTriple aColor( rgb2hsl( getRed(),
424cdf0e10cSrcweir                                                  getGreen(),
425cdf0e10cSrcweir                                                  getBlue() ) );
426cdf0e10cSrcweir             return HSLColor( aColor.mnHue, aColor.mnSaturation, aColor.mnLuminance );
427cdf0e10cSrcweir         }
428cdf0e10cSrcweir 
getIntegerColor() const429cdf0e10cSrcweir         ::cppcanvas::Color::IntSRGBA RGBColor::getIntegerColor() const
430cdf0e10cSrcweir         {
431cdf0e10cSrcweir             return ::cppcanvas::makeColor( colorToInt( getRed() ),
432cdf0e10cSrcweir                                            colorToInt( getGreen() ),
433cdf0e10cSrcweir                                            colorToInt( getBlue() ),
434cdf0e10cSrcweir                                            255 );
435cdf0e10cSrcweir         }
436cdf0e10cSrcweir 
operator +(const RGBColor & rLHS,const RGBColor & rRHS)437cdf0e10cSrcweir         RGBColor operator+( const RGBColor& rLHS, const RGBColor& rRHS )
438cdf0e10cSrcweir         {
439cdf0e10cSrcweir             return RGBColor( rLHS.getRed() + rRHS.getRed(),
440cdf0e10cSrcweir                              rLHS.getGreen() + rRHS.getGreen(),
441cdf0e10cSrcweir                              rLHS.getBlue() + rRHS.getBlue() );
442cdf0e10cSrcweir         }
443cdf0e10cSrcweir 
operator *(const RGBColor & rLHS,const RGBColor & rRHS)444cdf0e10cSrcweir         RGBColor operator*( const RGBColor& rLHS, const RGBColor& rRHS )
445cdf0e10cSrcweir         {
446cdf0e10cSrcweir             return RGBColor( rLHS.getRed() * rRHS.getRed(),
447cdf0e10cSrcweir                              rLHS.getGreen() * rRHS.getGreen(),
448cdf0e10cSrcweir                              rLHS.getBlue() * rRHS.getBlue() );
449cdf0e10cSrcweir         }
450cdf0e10cSrcweir 
operator *(double nFactor,const RGBColor & rRHS)451cdf0e10cSrcweir         RGBColor operator*( double nFactor, const RGBColor& rRHS )
452cdf0e10cSrcweir         {
453cdf0e10cSrcweir             return RGBColor( nFactor * rRHS.getRed(),
454cdf0e10cSrcweir                              nFactor * rRHS.getGreen(),
455cdf0e10cSrcweir                              nFactor * rRHS.getBlue() );
456cdf0e10cSrcweir         }
457cdf0e10cSrcweir 
interpolate(const RGBColor & rFrom,const RGBColor & rTo,double t)458cdf0e10cSrcweir         RGBColor interpolate( const RGBColor& rFrom, const RGBColor& rTo, double t )
459cdf0e10cSrcweir         {
460cdf0e10cSrcweir             return RGBColor( (1.0-t)*rFrom.getRed() + t*rTo.getRed(),
461cdf0e10cSrcweir                              (1.0-t)*rFrom.getGreen() + t*rTo.getGreen(),
462cdf0e10cSrcweir                              (1.0-t)*rFrom.getBlue() + t*rTo.getBlue() );
463cdf0e10cSrcweir         }
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir }
466