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 .
22 #include <tools/color.hxx>
23 #include <tools/debug.hxx>
24 #include <tools/stream.hxx>
25 #include <tools/rc.hxx>
26 #include <tools/rcid.h>
27 #include <tools/resid.hxx>
30 static inline long _FRound( double fVal
)
32 return( fVal
> 0.0 ? (long) ( fVal
+ 0.5 ) : -(long) ( -fVal
+ 0.5 ) );
35 Color::Color( const ResId
& rResId
)
37 rResId
.SetRT( RSC_COLOR
);
38 ResMgr
* pResMgr
= rResId
.GetResMgr();
39 if ( pResMgr
&& pResMgr
->GetResource( rResId
) )
41 // Header ueberspringen
42 pResMgr
->Increment( sizeof( RSHEADER_TYPE
) );
45 sal_uInt16 nRed
= pResMgr
->ReadShort();
46 sal_uInt16 nGreen
= pResMgr
->ReadShort();
47 sal_uInt16 nBlue
= pResMgr
->ReadShort();
48 // one more historical sal_uIntPtr
52 mnColor
= RGB_COLORDATA( nRed
>>8, nGreen
>>8, nBlue
>>8 );
56 mnColor
= RGB_COLORDATA( 0, 0, 0 );
60 sal_uInt8
Color::GetColorError( const Color
& rCompareColor
) const
62 const long nErrAbs
= labs( (long) rCompareColor
.GetRed() - GetRed() ) +
63 labs( (long) rCompareColor
.GetGreen() - GetGreen() ) +
64 labs( (long) rCompareColor
.GetBlue() - GetBlue() );
66 return (sal_uInt8
) _FRound( nErrAbs
* 0.3333333333 );
69 void Color::IncreaseLuminance( sal_uInt8 cLumInc
)
71 SetRed( (sal_uInt8
) SAL_BOUND( (long) COLORDATA_RED( mnColor
) + cLumInc
, 0L, 255L ) );
72 SetGreen( (sal_uInt8
) SAL_BOUND( (long) COLORDATA_GREEN( mnColor
) + cLumInc
, 0L, 255L ) );
73 SetBlue( (sal_uInt8
) SAL_BOUND( (long) COLORDATA_BLUE( mnColor
) + cLumInc
, 0L, 255L ) );
76 void Color::DecreaseLuminance( sal_uInt8 cLumDec
)
78 SetRed( (sal_uInt8
) SAL_BOUND( (long) COLORDATA_RED( mnColor
) - cLumDec
, 0L, 255L ) );
79 SetGreen( (sal_uInt8
) SAL_BOUND( (long) COLORDATA_GREEN( mnColor
) - cLumDec
, 0L, 255L ) );
80 SetBlue( (sal_uInt8
) SAL_BOUND( (long) COLORDATA_BLUE( mnColor
) - cLumDec
, 0L, 255L ) );
83 void Color::DecreaseContrast( sal_uInt8 cContDec
)
87 const double fM
= ( 128.0 - 0.4985 * cContDec
) / 128.0;
88 const double fOff
= 128.0 - fM
* 128.0;
90 SetRed( (sal_uInt8
) SAL_BOUND( _FRound( COLORDATA_RED( mnColor
) * fM
+ fOff
), 0L, 255L ) );
91 SetGreen( (sal_uInt8
) SAL_BOUND( _FRound( COLORDATA_GREEN( mnColor
) * fM
+ fOff
), 0L, 255L ) );
92 SetBlue( (sal_uInt8
) SAL_BOUND( _FRound( COLORDATA_BLUE( mnColor
) * fM
+ fOff
), 0L, 255L ) );
98 SetRed( ~COLORDATA_RED( mnColor
) );
99 SetGreen( ~COLORDATA_GREEN( mnColor
) );
100 SetBlue( ~COLORDATA_BLUE( mnColor
) );
103 sal_Bool
Color::IsDark() const
105 return GetLuminance() <= 60;
108 sal_Bool
Color::IsBright() const
110 return GetLuminance() >= 245;
113 // color space conversion
115 void Color::RGBtoHSB( sal_uInt16
& nHue
, sal_uInt16
& nSat
, sal_uInt16
& nBri
) const
118 sal_uInt8 cMax
, cMin
;
130 // Brightness = max(R, G, B);
131 nBri
= cMax
* 100 / 255;
139 sal_uInt8 cDelta
= cMax
- cMin
;
141 // Saturation = max - min / max
143 nSat
= cDelta
* 100 / cMax
;
148 nHue
= 0; // Default = undefined
155 dHue
= (double)( c
[1] - c
[2] ) / (double)cDelta
;
157 else if( c
[1] == cMax
)
159 dHue
= 2.0 + (double)( c
[2] - c
[0] ) / (double)cDelta
;
161 else if ( c
[2] == cMax
)
163 dHue
= 4.0 + (double)( c
[0] - c
[1] ) / (double)cDelta
;
170 nHue
= (sal_uInt16
) dHue
;
174 ColorData
Color::HSBtoRGB( sal_uInt16 nHue
, sal_uInt16 nSat
, sal_uInt16 nBri
)
176 sal_uInt8 cR
=0,cG
=0,cB
=0;
177 sal_uInt8 nB
= (sal_uInt8
) ( nBri
* 255 / 100 );
197 sal_uInt8 a
= (sal_uInt8
) ( nB
* ( 100 - nSat
) / 100 );
198 sal_uInt8 b
= (sal_uInt8
) ( nB
* ( 100 - ( (double)nSat
* f
) ) / 100 );
199 sal_uInt8 c
= (sal_uInt8
) ( nB
* ( 100 - ( (double)nSat
* ( 1.0 - f
) ) ) / 100 );
203 case 0: cR
= nB
; cG
= c
; cB
= a
; break;
204 case 1: cR
= b
; cG
= nB
; cB
= a
; break;
205 case 2: cR
= a
; cG
= nB
; cB
= c
; break;
206 case 3: cR
= a
; cG
= b
; cB
= nB
; break;
207 case 4: cR
= c
; cG
= a
; cB
= nB
; break;
208 case 5: cR
= nB
; cG
= a
; cB
= b
; break;
212 return RGB_COLORDATA( cR
, cG
, cB
);
215 SvStream
& Color::Read( SvStream
& rIStm
, sal_Bool bNewFormat
)
225 SvStream
& Color::Write( SvStream
& rOStm
, sal_Bool bNewFormat
)
235 #define COL_NAME_USER ((sal_uInt16)0x8000)
237 SvStream
& operator>>( SvStream
& rIStream
, Color
& rColor
)
239 DBG_ASSERTWARNING( rIStream
.GetVersion(), "Color::>> - Solar-Version not set on rIStream" );
241 sal_uInt16 nColorName
;
243 rIStream
>> nColorName
;
245 if ( nColorName
& COL_NAME_USER
)
255 rColor
.mnColor
= RGB_COLORDATA( nRed
>>8, nGreen
>>8, nBlue
>>8 );
259 static ColorData aColAry
[] =
261 COL_BLACK
, // COL_BLACK
262 COL_BLUE
, // COL_BLUE
263 COL_GREEN
, // COL_GREEN
264 COL_CYAN
, // COL_CYAN
266 COL_MAGENTA
, // COL_MAGENTA
267 COL_BROWN
, // COL_BROWN
268 COL_GRAY
, // COL_GRAY
269 COL_LIGHTGRAY
, // COL_LIGHTGRAY
270 COL_LIGHTBLUE
, // COL_LIGHTBLUE
271 COL_LIGHTGREEN
, // COL_LIGHTGREEN
272 COL_LIGHTCYAN
, // COL_LIGHTCYAN
273 COL_LIGHTRED
, // COL_LIGHTRED
274 COL_LIGHTMAGENTA
, // COL_LIGHTMAGENTA
275 COL_YELLOW
, // COL_YELLOW
276 COL_WHITE
, // COL_WHITE
277 COL_WHITE
, // COL_MENUBAR
278 COL_BLACK
, // COL_MENUBARTEXT
279 COL_WHITE
, // COL_POPUPMENU
280 COL_BLACK
, // COL_POPUPMENUTEXT
281 COL_BLACK
, // COL_WINDOWTEXT
282 COL_WHITE
, // COL_WINDOWWORKSPACE
283 COL_BLACK
, // COL_HIGHLIGHT
284 COL_WHITE
, // COL_HIGHLIGHTTEXT
285 COL_BLACK
, // COL_3DTEXT
286 COL_LIGHTGRAY
, // COL_3DFACE
287 COL_WHITE
, // COL_3DLIGHT
288 COL_GRAY
, // COL_3DSHADOW
289 COL_LIGHTGRAY
, // COL_SCROLLBAR
290 COL_WHITE
, // COL_FIELD
291 COL_BLACK
// COL_FIELDTEXT
294 if ( nColorName
< (sizeof( aColAry
)/sizeof(ColorData
)) )
295 rColor
.mnColor
= aColAry
[nColorName
];
297 rColor
.mnColor
= COL_BLACK
;
303 SvStream
& operator<<( SvStream
& rOStream
, const Color
& rColor
)
305 DBG_ASSERTWARNING( rOStream
.GetVersion(), "Color::<< - Solar-Version not set on rOStream" );
307 sal_uInt16 nColorName
= COL_NAME_USER
;
308 sal_uInt16 nRed
= rColor
.GetRed();
309 sal_uInt16 nGreen
= rColor
.GetGreen();
310 sal_uInt16 nBlue
= rColor
.GetBlue();
311 nRed
= (nRed
<<8) + nRed
;
312 nGreen
= (nGreen
<<8) + nGreen
;
313 nBlue
= (nBlue
<<8) + nBlue
;
315 rOStream
<< nColorName
;
323 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */