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 <sal/config.h>
27 #include <tools/color.hxx>
28 #include <tools/helpers.hxx>
29 #include <tools/long.hxx>
30 #include <basegfx/color/bcolortools.hxx>
32 void Color::IncreaseLuminance(sal_uInt8 cLumInc
)
34 R
= sal_uInt8(std::clamp(R
+ cLumInc
, 0, 255));
35 G
= sal_uInt8(std::clamp(G
+ cLumInc
, 0, 255));
36 B
= sal_uInt8(std::clamp(B
+ cLumInc
, 0, 255));
39 void Color::DecreaseLuminance(sal_uInt8 cLumDec
)
41 R
= sal_uInt8(std::clamp(R
- cLumDec
, 0, 255));
42 G
= sal_uInt8(std::clamp(G
- cLumDec
, 0, 255));
43 B
= sal_uInt8(std::clamp(B
- cLumDec
, 0, 255));
46 void Color::DecreaseContrast(sal_uInt8 nContDec
)
50 const double fM
= (128.0 - 0.4985 * nContDec
) / 128.0;
51 const double fOff
= 128.0 - fM
* 128.0;
53 R
= sal_uInt8(std::clamp(FRound(R
* fM
+ fOff
), tools::Long(0), tools::Long(255)));
54 G
= sal_uInt8(std::clamp(FRound(G
* fM
+ fOff
), tools::Long(0), tools::Long(255)));
55 B
= sal_uInt8(std::clamp(FRound(B
* fM
+ fOff
), tools::Long(0), tools::Long(255)));
59 // color space conversion
61 void Color::RGBtoHSB( sal_uInt16
& nHue
, sal_uInt16
& nSat
, sal_uInt16
& nBri
) const
76 // Brightness = max(R, G, B);
77 nBri
= cMax
* 100 / 255;
85 sal_uInt8 cDelta
= cMax
- cMin
;
87 // Saturation = max - min / max
89 nSat
= cDelta
* 100 / cMax
;
94 nHue
= 0; // Default = undefined
101 dHue
= static_cast<double>( c
[1] - c
[2] ) / static_cast<double>(cDelta
);
103 else if( c
[1] == cMax
)
105 dHue
= 2.0 + static_cast<double>( c
[2] - c
[0] ) / static_cast<double>(cDelta
);
107 else if ( c
[2] == cMax
)
109 dHue
= 4.0 + static_cast<double>( c
[0] - c
[1] ) / static_cast<double>(cDelta
);
116 nHue
= static_cast<sal_uInt16
>(dHue
);
120 Color
Color::HSBtoRGB( sal_uInt16 nHue
, sal_uInt16 nSat
, sal_uInt16 nBri
)
122 sal_uInt8 cR
=0,cG
=0,cB
=0;
123 sal_uInt8 nB
= static_cast<sal_uInt8
>( nBri
* 255 / 100 );
140 n
= static_cast<sal_uInt16
>(dH
);
143 sal_uInt8 a
= static_cast<sal_uInt8
>( nB
* ( 100 - nSat
) / 100 );
144 sal_uInt8 b
= static_cast<sal_uInt8
>( nB
* ( 100 - ( static_cast<double>(nSat
) * f
) ) / 100 );
145 sal_uInt8 c
= static_cast<sal_uInt8
>( nB
* ( 100 - ( static_cast<double>(nSat
) * ( 1.0 - f
) ) ) / 100 );
149 case 0: cR
= nB
; cG
= c
; cB
= a
; break;
150 case 1: cR
= b
; cG
= nB
; cB
= a
; break;
151 case 2: cR
= a
; cG
= nB
; cB
= c
; break;
152 case 3: cR
= a
; cG
= b
; cB
= nB
; break;
153 case 4: cR
= c
; cG
= a
; cB
= nB
; break;
154 case 5: cR
= nB
; cG
= a
; cB
= b
; break;
158 return Color( cR
, cG
, cB
);
161 Color
Color::STRtoRGB(const OUString
& colorname
)
164 if(colorname
.isEmpty()) return col
;
166 switch(colorname
.getLength()){
168 col
.mValue
= colorname
.copy(1,6).toUInt32(16);
171 col
.mValue
= colorname
.toUInt32(16);
175 sal_Unicode data
[6] = { colorname
[1], colorname
[1], colorname
[2],
176 colorname
[2], colorname
[3], colorname
[3] };
177 col
.mValue
= OUString(data
,6).toUInt32(16);
182 sal_Unicode data
[6] = { colorname
[0], colorname
[0], colorname
[1],
183 colorname
[1], colorname
[2], colorname
[2] };
184 col
.mValue
= OUString(data
,6).toUInt32(16);
193 OUString
Color::AsRGBHexString() const
195 std::stringstream ss
;
196 ss
<< std::hex
<< std::setfill ('0') << std::setw(6) << sal_uInt32(GetRGBColor());
197 return OUString::createFromAscii(ss
.str().c_str());
200 OUString
Color::AsRGBHEXString() const
202 std::stringstream ss
;
203 ss
<< std::hex
<< std::uppercase
<< std::setfill ('0') << std::setw(6) << sal_uInt32(GetRGBColor());
204 return OUString::createFromAscii(ss
.str().c_str());
207 void Color::ApplyTintOrShade(sal_Int16 n100thPercent
)
209 if (n100thPercent
== 0)
212 basegfx::BColor aBColor
= basegfx::utils::rgb2hsl(getBColor());
213 double fFactor
= 1.0 - (std::abs(double(n100thPercent
)) / 10000.0);
216 if (n100thPercent
> 0) // tint
218 fResult
= aBColor
.getBlue() * fFactor
+ (1.0 - fFactor
);
222 fResult
= aBColor
.getBlue() * fFactor
;
225 aBColor
.setBlue(fResult
);
226 aBColor
= basegfx::utils::hsl2rgb(aBColor
);
228 R
= sal_uInt8(std::lround(aBColor
.getRed() * 255.0));
229 G
= sal_uInt8(std::lround(aBColor
.getGreen() * 255.0));
230 B
= sal_uInt8(std::lround(aBColor
.getBlue() * 255.0));
233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */