1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: color.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
35 #include <vos/macros.hxx>
36 #include <tools/color.hxx>
37 #include <tools/debug.hxx>
38 #include <tools/stream.hxx>
39 #include <tools/rc.hxx>
40 #include <tools/rcid.h>
41 #include <tools/resid.hxx>
50 static inline long _FRound( double fVal
)
52 return( fVal
> 0.0 ? (long) ( fVal
+ 0.5 ) : -(long) ( -fVal
+ 0.5 ) );
59 Color::Color( const ResId
& rResId
)
61 rResId
.SetRT( RSC_COLOR
);
62 ResMgr
* pResMgr
= rResId
.GetResMgr();
63 if ( pResMgr
&& pResMgr
->GetResource( rResId
) )
65 // Header ueberspringen
66 pResMgr
->Increment( sizeof( RSHEADER_TYPE
) );
69 USHORT nRed
= pResMgr
->ReadShort();
70 USHORT nGreen
= pResMgr
->ReadShort();
71 USHORT nBlue
= pResMgr
->ReadShort();
72 // one more historical ULONG
76 mnColor
= RGB_COLORDATA( nRed
>>8, nGreen
>>8, nBlue
>>8 );
80 mnColor
= RGB_COLORDATA( 0, 0, 0 );
83 UINT8
Color::GetColorError( const Color
& rCompareColor
) const
85 const long nErrAbs
= labs( (long) rCompareColor
.GetRed() - GetRed() ) +
86 labs( (long) rCompareColor
.GetGreen() - GetGreen() ) +
87 labs( (long) rCompareColor
.GetBlue() - GetBlue() );
89 return (UINT8
) _FRound( nErrAbs
* 0.3333333333 );
92 // -----------------------------------------------------------------------
94 void Color::IncreaseLuminance( UINT8 cLumInc
)
96 SetRed( (UINT8
) VOS_BOUND( (long) COLORDATA_RED( mnColor
) + cLumInc
, 0L, 255L ) );
97 SetGreen( (UINT8
) VOS_BOUND( (long) COLORDATA_GREEN( mnColor
) + cLumInc
, 0L, 255L ) );
98 SetBlue( (UINT8
) VOS_BOUND( (long) COLORDATA_BLUE( mnColor
) + cLumInc
, 0L, 255L ) );
101 // -----------------------------------------------------------------------
103 void Color::DecreaseLuminance( UINT8 cLumDec
)
105 SetRed( (UINT8
) VOS_BOUND( (long) COLORDATA_RED( mnColor
) - cLumDec
, 0L, 255L ) );
106 SetGreen( (UINT8
) VOS_BOUND( (long) COLORDATA_GREEN( mnColor
) - cLumDec
, 0L, 255L ) );
107 SetBlue( (UINT8
) VOS_BOUND( (long) COLORDATA_BLUE( mnColor
) - cLumDec
, 0L, 255L ) );
110 // -----------------------------------------------------------------------
112 void Color::IncreaseContrast( UINT8 cContInc
)
116 const double fM
= 128.0 / ( 128.0 - 0.4985 * cContInc
);
117 const double fOff
= 128.0 - fM
* 128.0;
119 SetRed( (UINT8
) VOS_BOUND( _FRound( COLORDATA_RED( mnColor
) * fM
+ fOff
), 0L, 255L ) );
120 SetGreen( (UINT8
) VOS_BOUND( _FRound( COLORDATA_GREEN( mnColor
) * fM
+ fOff
), 0L, 255L ) );
121 SetBlue( (UINT8
) VOS_BOUND( _FRound( COLORDATA_BLUE( mnColor
) * fM
+ fOff
), 0L, 255L ) );
125 // -----------------------------------------------------------------------
127 void Color::DecreaseContrast( UINT8 cContDec
)
131 const double fM
= ( 128.0 - 0.4985 * cContDec
) / 128.0;
132 const double fOff
= 128.0 - fM
* 128.0;
134 SetRed( (UINT8
) VOS_BOUND( _FRound( COLORDATA_RED( mnColor
) * fM
+ fOff
), 0L, 255L ) );
135 SetGreen( (UINT8
) VOS_BOUND( _FRound( COLORDATA_GREEN( mnColor
) * fM
+ fOff
), 0L, 255L ) );
136 SetBlue( (UINT8
) VOS_BOUND( _FRound( COLORDATA_BLUE( mnColor
) * fM
+ fOff
), 0L, 255L ) );
140 // -----------------------------------------------------------------------
144 SetRed( ~COLORDATA_RED( mnColor
) );
145 SetGreen( ~COLORDATA_GREEN( mnColor
) );
146 SetBlue( ~COLORDATA_BLUE( mnColor
) );
149 // -----------------------------------------------------------------------
151 BOOL
Color::IsDark() const
153 return GetLuminance() <= 38;
156 // -----------------------------------------------------------------------
158 BOOL
Color::IsBright() const
160 return GetLuminance() >= 245;
163 // -----------------------------------------------------------------------
164 // color space conversion
165 // -----------------------------------------------------------------------
167 void Color::RGBtoHSB( USHORT
& nHue
, USHORT
& nSat
, USHORT
& nBri
) const
182 // Brightness = max(R, G, B);
183 nBri
= cMax
* 100 / 255;
191 UINT8 cDelta
= cMax
- cMin
;
193 // Saturation = max - min / max
195 nSat
= cDelta
* 100 / cMax
;
200 nHue
= 0; // Default = undefined
207 dHue
= (double)( c
[1] - c
[2] ) / (double)cDelta
;
209 else if( c
[1] == cMax
)
211 dHue
= 2.0 + (double)( c
[2] - c
[0] ) / (double)cDelta
;
213 else if ( c
[2] == cMax
)
215 dHue
= 4.0 + (double)( c
[0] - c
[1] ) / (double)cDelta
;
222 nHue
= (UINT16
) dHue
;
226 ColorData
Color::HSBtoRGB( USHORT nHue
, USHORT nSat
, USHORT nBri
)
228 UINT8 cR
=0,cG
=0,cB
=0;
229 UINT8 nB
= (UINT8
) ( nBri
* 255 / 100 );
249 UINT8 a
= (UINT8
) ( nB
* ( 100 - nSat
) / 100 );
250 UINT8 b
= (UINT8
) ( nB
* ( 100 - ( (double)nSat
* f
+ 0.5 ) ) / 100 );
251 UINT8 c
= (UINT8
) ( nB
* ( 100 - ( (double)nSat
* ( 1.0 - f
) + 0.5 ) ) / 100 );
255 case 0: cR
= nB
; cG
= c
; cB
= a
; break;
256 case 1: cR
= b
; cG
= nB
; cB
= a
; break;
257 case 2: cR
= a
; cG
= nB
; cB
= c
; break;
258 case 3: cR
= a
; cG
= b
; cB
= nB
; break;
259 case 4: cR
= c
; cG
= a
; cB
= nB
; break;
260 case 5: cR
= nB
; cG
= a
; cB
= b
; break;
264 return RGB_COLORDATA( cR
, cG
, cB
);
267 // -----------------------------------------------------------------------
269 SvStream
& Color::Read( SvStream
& rIStm
, BOOL bNewFormat
)
279 // -----------------------------------------------------------------------
281 SvStream
& Color::Write( SvStream
& rOStm
, BOOL bNewFormat
)
291 // -----------------------------------------------------------------------
293 #define COL_NAME_USER ((USHORT)0x8000)
294 #define COL_RED_1B ((USHORT)0x0001)
295 #define COL_RED_2B ((USHORT)0x0002)
296 #define COL_GREEN_1B ((USHORT)0x0010)
297 #define COL_GREEN_2B ((USHORT)0x0020)
298 #define COL_BLUE_1B ((USHORT)0x0100)
299 #define COL_BLUE_2B ((USHORT)0x0200)
301 // -----------------------------------------------------------------------
303 SvStream
& operator>>( SvStream
& rIStream
, Color
& rColor
)
305 DBG_ASSERTWARNING( rIStream
.GetVersion(), "Color::>> - Solar-Version not set on rIStream" );
312 rIStream
>> nColorName
;
314 if ( nColorName
& COL_NAME_USER
)
316 if ( rIStream
.GetCompressMode() == COMPRESSMODE_FULL
)
318 unsigned char cAry
[6];
325 if ( nColorName
& COL_RED_2B
)
327 else if ( nColorName
& COL_RED_1B
)
329 if ( nColorName
& COL_GREEN_2B
)
331 else if ( nColorName
& COL_GREEN_1B
)
333 if ( nColorName
& COL_BLUE_2B
)
335 else if ( nColorName
& COL_BLUE_1B
)
338 rIStream
.Read( cAry
, i
);
341 if ( nColorName
& COL_RED_2B
)
349 else if ( nColorName
& COL_RED_1B
)
355 if ( nColorName
& COL_GREEN_2B
)
363 else if ( nColorName
& COL_GREEN_1B
)
369 if ( nColorName
& COL_BLUE_2B
)
377 else if ( nColorName
& COL_BLUE_1B
)
391 rColor
.mnColor
= RGB_COLORDATA( nRed
>>8, nGreen
>>8, nBlue
>>8 );
395 static ColorData aColAry
[] =
397 COL_BLACK
, // COL_BLACK
398 COL_BLUE
, // COL_BLUE
399 COL_GREEN
, // COL_GREEN
400 COL_CYAN
, // COL_CYAN
402 COL_MAGENTA
, // COL_MAGENTA
403 COL_BROWN
, // COL_BROWN
404 COL_GRAY
, // COL_GRAY
405 COL_LIGHTGRAY
, // COL_LIGHTGRAY
406 COL_LIGHTBLUE
, // COL_LIGHTBLUE
407 COL_LIGHTGREEN
, // COL_LIGHTGREEN
408 COL_LIGHTCYAN
, // COL_LIGHTCYAN
409 COL_LIGHTRED
, // COL_LIGHTRED
410 COL_LIGHTMAGENTA
, // COL_LIGHTMAGENTA
411 COL_YELLOW
, // COL_YELLOW
412 COL_WHITE
, // COL_WHITE
413 COL_WHITE
, // COL_MENUBAR
414 COL_BLACK
, // COL_MENUBARTEXT
415 COL_WHITE
, // COL_POPUPMENU
416 COL_BLACK
, // COL_POPUPMENUTEXT
417 COL_BLACK
, // COL_WINDOWTEXT
418 COL_WHITE
, // COL_WINDOWWORKSPACE
419 COL_BLACK
, // COL_HIGHLIGHT
420 COL_WHITE
, // COL_HIGHLIGHTTEXT
421 COL_BLACK
, // COL_3DTEXT
422 COL_LIGHTGRAY
, // COL_3DFACE
423 COL_WHITE
, // COL_3DLIGHT
424 COL_GRAY
, // COL_3DSHADOW
425 COL_LIGHTGRAY
, // COL_SCROLLBAR
426 COL_WHITE
, // COL_FIELD
427 COL_BLACK
// COL_FIELDTEXT
430 if ( nColorName
< (sizeof( aColAry
)/sizeof(ColorData
)) )
431 rColor
.mnColor
= aColAry
[nColorName
];
433 rColor
.mnColor
= COL_BLACK
;
439 // -----------------------------------------------------------------------
441 SvStream
& operator<<( SvStream
& rOStream
, const Color
& rColor
)
443 DBG_ASSERTWARNING( rOStream
.GetVersion(), "Color::<< - Solar-Version not set on rOStream" );
445 USHORT nColorName
= COL_NAME_USER
;
446 USHORT nRed
= rColor
.GetRed();
447 USHORT nGreen
= rColor
.GetGreen();
448 USHORT nBlue
= rColor
.GetBlue();
449 nRed
= (nRed
<<8) + nRed
;
450 nGreen
= (nGreen
<<8) + nGreen
;
451 nBlue
= (nBlue
<<8) + nBlue
;
453 if ( rOStream
.GetCompressMode() == COMPRESSMODE_FULL
)
455 unsigned char cAry
[6];
460 nColorName
|= COL_RED_2B
;
461 cAry
[i
] = (unsigned char)(nRed
& 0xFF);
463 cAry
[i
] = (unsigned char)((nRed
>> 8) & 0xFF);
466 else if ( nRed
& 0xFF00 )
468 nColorName
|= COL_RED_1B
;
469 cAry
[i
] = (unsigned char)((nRed
>> 8) & 0xFF);
472 if ( nGreen
& 0x00FF )
474 nColorName
|= COL_GREEN_2B
;
475 cAry
[i
] = (unsigned char)(nGreen
& 0xFF);
477 cAry
[i
] = (unsigned char)((nGreen
>> 8) & 0xFF);
480 else if ( nGreen
& 0xFF00 )
482 nColorName
|= COL_GREEN_1B
;
483 cAry
[i
] = (unsigned char)((nGreen
>> 8) & 0xFF);
486 if ( nBlue
& 0x00FF )
488 nColorName
|= COL_BLUE_2B
;
489 cAry
[i
] = (unsigned char)(nBlue
& 0xFF);
491 cAry
[i
] = (unsigned char)((nBlue
>> 8) & 0xFF);
494 else if ( nBlue
& 0xFF00 )
496 nColorName
|= COL_BLUE_1B
;
497 cAry
[i
] = (unsigned char)((nBlue
>> 8) & 0xFF);
501 rOStream
<< nColorName
;
502 rOStream
.Write( cAry
, i
);
506 rOStream
<< nColorName
;