1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <basegfx/numeric/ftools.hxx>
21 #include <basegfx/color/bcolor.hxx>
22 #include <basegfx/color/bcolortools.hxx>
24 namespace basegfx
{ namespace utils
26 BColor
rgb2hsl(const BColor
& rRGBColor
)
28 const double r
=rRGBColor
.getRed(), g
=rRGBColor
.getGreen(), b
=rRGBColor
.getBlue();
29 const double minVal
= std::min( std::min( r
, g
), b
);
30 const double maxVal
= std::max( std::max( r
, g
), b
);
31 const double d
= maxVal
- minVal
;
35 l
= (maxVal
+ minVal
) / 2.0;
37 if( ::basegfx::fTools::equalZero(d
) )
39 s
= h
= 0; // hue undefined (achromatic case)
43 s
= l
> 0.5 ? d
/(2.0-maxVal
-minVal
) :
46 if( rtl::math::approxEqual(r
, maxVal
) )
48 else if( rtl::math::approxEqual(g
, maxVal
) )
62 static double hsl2rgbHelper( double nValue1
, double nValue2
, double nHue
)
64 // clamp hue to [0,360]
65 nHue
= fmod( nHue
, 360.0 );
67 // cope with wrap-arounds
72 return nValue1
+ (nValue2
- nValue1
)*nHue
/60.0;
73 else if( nHue
< 180.0 )
75 else if( nHue
< 240.0 )
76 return nValue1
+ (nValue2
- nValue1
)*(240.0 - nHue
)/60.0;
81 BColor
hsl2rgb(const BColor
& rHSLColor
)
83 const double h
=rHSLColor
.getRed(), s
=rHSLColor
.getGreen(), l
=rHSLColor
.getBlue();
85 if( fTools::equalZero(s
) )
86 return BColor(l
, l
, l
); // achromatic case
88 const double nVal1( l
<= 0.5 ? l
*(1.0 + s
) : l
+ s
- l
*s
);
89 const double nVal2( 2.0*l
- nVal1
);
103 BColor
rgb2hsv(const BColor
& rRGBColor
)
105 const double r
=rRGBColor
.getRed(), g
=rRGBColor
.getGreen(), b
=rRGBColor
.getBlue();
106 const double maxVal
= std::max(std::max(r
,g
),b
);
107 const double minVal
= std::min(std::min(r
,g
),b
);
108 const double delta
= maxVal
-minVal
;
110 double h
=0, s
=0, v
=0;
113 if( fTools::equalZero(v
) )
118 if( !fTools::equalZero(s
) )
120 if( rtl::math::approxEqual(maxVal
, r
) )
124 else if( rtl::math::approxEqual(maxVal
, g
) )
126 h
= 2.0 + (b
- r
) / delta
;
130 h
= 4.0 + (r
- g
) / delta
;
139 return BColor(h
,s
,v
);
142 BColor
hsv2rgb(const BColor
& rHSVColor
)
144 double h
=rHSVColor
.getRed();
145 const double s
=rHSVColor
.getGreen(), v
=rHSVColor
.getBlue();
147 if( fTools::equalZero(s
) )
149 // achromatic case: no hue.
150 return BColor(v
,v
,v
);
154 if( fTools::equal(h
,360) )
155 h
= 0; // 360 degrees is equivalent to 0 degrees
158 const sal_Int32 intval
= static_cast< sal_Int32
>( h
);
159 const double f
= h
- intval
;
160 const double p
= v
*(1.0-s
);
161 const double q
= v
*(1.0-(s
*f
));
162 const double t
= v
*(1.0-(s
*(1.0-f
)));
164 /* which hue area? */
168 return BColor(v
,t
,p
);
171 return BColor(q
,v
,p
);
174 return BColor(p
,v
,t
);
177 return BColor(p
,q
,v
);
180 return BColor(t
,p
,v
);
183 return BColor(v
,p
,q
);
192 } } // end of namespace basegfx
194 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */