LibreOffice Module basegfx (master) 1
bcolortools.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
23#include <rtl/math.hxx>
24
25namespace basegfx::utils
26{
27 BColor rgb2hsl(const BColor& rRGBColor)
28 {
29 const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
30 const double minVal = std::min( std::min( r, g ), b );
31 const double maxVal = std::max( std::max( r, g ), b );
32 const double d = maxVal - minVal;
33
34 double h=0, s=0, l=0;
35
36 l = (maxVal + minVal) / 2.0;
37
39 {
40 s = h = 0; // hue undefined (achromatic case)
41 }
42 else
43 {
44 s = l > 0.5 ? d/(2.0-maxVal-minVal) :
45 d/(maxVal + minVal);
46
47 if( rtl::math::approxEqual(r, maxVal) )
48 h = (g - b)/d;
49 else if( rtl::math::approxEqual(g, maxVal) )
50 h = 2.0 + (b - r)/d;
51 else
52 h = 4.0 + (r - g)/d;
53
54 h *= 60.0;
55
56 if( h < 0.0 )
57 h += 360.0;
58 }
59
60 return BColor(h,s,l);
61 }
62
63 static double hsl2rgbHelper( double nValue1, double nValue2, double nHue )
64 {
65 // clamp hue to [0,360]
66 nHue = fmod( nHue, 360.0 );
67
68 // cope with wrap-arounds
69 if( nHue < 0.0 )
70 nHue += 360.0;
71
72 if( nHue < 60.0 )
73 return nValue1 + (nValue2 - nValue1)*nHue/60.0;
74 else if( nHue < 180.0 )
75 return nValue2;
76 else if( nHue < 240.0 )
77 return nValue1 + (nValue2 - nValue1)*(240.0 - nHue)/60.0;
78 else
79 return nValue1;
80 }
81
82 BColor hsl2rgb(const BColor& rHSLColor)
83 {
84 const double h=rHSLColor.getRed(), s=rHSLColor.getGreen(), l=rHSLColor.getBlue();
85
86 if( fTools::equalZero(s) )
87 return BColor(l, l, l ); // achromatic case
88
89 const double nVal1( l <= 0.5 ? l*(1.0 + s) : l + s - l*s );
90 const double nVal2( 2.0*l - nVal1 );
91
92 return BColor(
93 hsl2rgbHelper(nVal2,
94 nVal1,
95 h + 120.0),
96 hsl2rgbHelper(nVal2,
97 nVal1,
98 h),
99 hsl2rgbHelper(nVal2,
100 nVal1,
101 h - 120.0) );
102 }
103
104 BColor rgb2hsv(const BColor& rRGBColor)
105 {
106 const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
107 const double maxVal = std::max(std::max(r,g),b);
108 const double minVal = std::min(std::min(r,g),b);
109 const double delta = maxVal-minVal;
110
111 double h=0, s=0, v=0;
112
113 v = maxVal;
114 if( fTools::equalZero(v) )
115 s = 0;
116 else
117 s = delta / v;
118
119 if( !fTools::equalZero(s) )
120 {
121 if( rtl::math::approxEqual(maxVal, r) )
122 {
123 h = (g - b) / delta;
124 }
125 else if( rtl::math::approxEqual(maxVal, g) )
126 {
127 h = 2.0 + (b - r) / delta;
128 }
129 else
130 {
131 h = 4.0 + (r - g) / delta;
132 }
133
134 h *= 60.0;
135
136 if( h < 0 )
137 h += 360;
138 }
139
140 return BColor(h,s,v);
141 }
142
143 BColor hsv2rgb(const BColor& rHSVColor)
144 {
145 double h=rHSVColor.getRed();
146 const double s=rHSVColor.getGreen(), v=rHSVColor.getBlue();
147
148 if( fTools::equalZero(s) )
149 {
150 // achromatic case: no hue.
151 return BColor(v,v,v);
152 }
153 else
154 {
155 if( fTools::equal(h, 360.0) )
156 h = 0; // 360 degrees is equivalent to 0 degrees
157
158 h /= 60.0;
159 const sal_Int32 intval = static_cast< sal_Int32 >( h );
160 const double f = h - intval;
161 const double p = v*(1.0-s);
162 const double q = v*(1.0-(s*f));
163 const double t = v*(1.0-(s*(1.0-f)));
164
165 /* which hue area? */
166 switch( intval )
167 {
168 case 0:
169 return BColor(v,t,p);
170
171 case 1:
172 return BColor(q,v,p);
173
174 case 2:
175 return BColor(p,v,t);
176
177 case 3:
178 return BColor(p,q,v);
179
180 case 4:
181 return BColor(t,p,v);
182
183 case 5:
184 return BColor(v,p,q);
185
186 default:
187 // hue overflow
188 return BColor();
189 }
190 }
191 }
192
193} // end of namespace
194
195/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
double d
Base Color class with three double values.
Definition: bcolor.hxx:41
double getBlue() const
Definition: bcolor.hxx:80
double getRed() const
Definition: bcolor.hxx:78
double getGreen() const
Definition: bcolor.hxx:79
float v
void * p
bool equalZero(const T &rfVal)
Compare against small value.
Definition: ftools.hxx:156
bool equal(T const &rfValA, T const &rfValB)
Definition: ftools.hxx:169
static double hsl2rgbHelper(double nValue1, double nValue2, double nHue)
Definition: bcolortools.cxx:63
BColor hsv2rgb(const BColor &rHSVColor)
Transform from HSV to RGB.
BColor rgb2hsv(const BColor &rRGBColor)
Transform from RGB to HSV.
BColor rgb2hsl(const BColor &rRGBColor)
Transform from RGB to HSL.
Definition: bcolortools.cxx:27
BColor hsl2rgb(const BColor &rHSLColor)
Transform from HSL to RGB.
Definition: bcolortools.cxx:82
sal_Int32 h