merge the formfield patch from ooo-build
[ooovba.git] / tools / source / generic / color.cxx
blob0d90aba28ea487f68fb02eef3b270ddba24d5cc5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: color.cxx,v $
10 * $Revision: 1.14 $
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"
34 #include <stdlib.h>
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>
42 #ifndef _SV_RC_H
43 #include <tools/rc.h>
44 #endif
46 // -----------
47 // - Inlines -
48 // -----------
50 static inline long _FRound( double fVal )
52 return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
55 // ---------
56 // - Color -
57 // ---------
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 ) );
68 // Daten laden
69 USHORT nRed = pResMgr->ReadShort();
70 USHORT nGreen = pResMgr->ReadShort();
71 USHORT nBlue = pResMgr->ReadShort();
72 // one more historical ULONG
73 pResMgr->ReadLong();
75 // RGB-Farbe
76 mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
78 else
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 )
114 if( 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 )
129 if( 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 // -----------------------------------------------------------------------
142 void Color::Invert()
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
169 UINT8 c[3];
170 UINT8 cMax, cMin;
172 c[0] = GetRed();
173 c[1] = GetGreen();
174 c[2] = GetBlue();
176 cMax = c[0];
177 if( c[1] > cMax )
178 cMax = c[1];
179 if( c[2] > cMax )
180 cMax = c[2];
182 // Brightness = max(R, G, B);
183 nBri = cMax * 100 / 255;
185 cMin = c[0];
186 if( c[1] < cMin )
187 cMin = c[1];
188 if( c[2] < cMin )
189 cMin = c[2];
191 UINT8 cDelta = cMax - cMin;
193 // Saturation = max - min / max
194 if( nBri > 0 )
195 nSat = cDelta * 100 / cMax;
196 else
197 nSat = 0;
199 if( nSat == 0 )
200 nHue = 0; // Default = undefined
201 else
203 double dHue = 0.0;
205 if( c[0] == cMax )
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;
217 dHue *= 60.0;
219 if( dHue < 0.0 )
220 dHue += 360.0;
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 );
231 if( nSat == 0 )
233 cR = nB;
234 cG = nB;
235 cB = nB;
237 else
239 double dH = nHue;
240 double f;
241 UINT16 n;
242 if( dH == 360.0 )
243 dH = 0.0;
245 dH /= 60.0;
246 n = (UINT16) dH;
247 f = dH - n;
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 );
253 switch( n )
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 )
271 if ( bNewFormat )
272 rIStm >> mnColor;
273 else
274 rIStm >> *this;
276 return rIStm;
279 // -----------------------------------------------------------------------
281 SvStream& Color::Write( SvStream& rOStm, BOOL bNewFormat )
283 if ( bNewFormat )
284 rOStm << mnColor;
285 else
286 rOStm << *this;
288 return rOStm;
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" );
307 USHORT nColorName;
308 USHORT nRed;
309 USHORT nGreen;
310 USHORT nBlue;
312 rIStream >> nColorName;
314 if ( nColorName & COL_NAME_USER )
316 if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
318 unsigned char cAry[6];
319 USHORT i = 0;
321 nRed = 0;
322 nGreen = 0;
323 nBlue = 0;
325 if ( nColorName & COL_RED_2B )
326 i += 2;
327 else if ( nColorName & COL_RED_1B )
328 i++;
329 if ( nColorName & COL_GREEN_2B )
330 i += 2;
331 else if ( nColorName & COL_GREEN_1B )
332 i++;
333 if ( nColorName & COL_BLUE_2B )
334 i += 2;
335 else if ( nColorName & COL_BLUE_1B )
336 i++;
338 rIStream.Read( cAry, i );
339 i = 0;
341 if ( nColorName & COL_RED_2B )
343 nRed = cAry[i];
344 nRed <<= 8;
345 i++;
346 nRed |= cAry[i];
347 i++;
349 else if ( nColorName & COL_RED_1B )
351 nRed = cAry[i];
352 nRed <<= 8;
353 i++;
355 if ( nColorName & COL_GREEN_2B )
357 nGreen = cAry[i];
358 nGreen <<= 8;
359 i++;
360 nGreen |= cAry[i];
361 i++;
363 else if ( nColorName & COL_GREEN_1B )
365 nGreen = cAry[i];
366 nGreen <<= 8;
367 i++;
369 if ( nColorName & COL_BLUE_2B )
371 nBlue = cAry[i];
372 nBlue <<= 8;
373 i++;
374 nBlue |= cAry[i];
375 i++;
377 else if ( nColorName & COL_BLUE_1B )
379 nBlue = cAry[i];
380 nBlue <<= 8;
381 i++;
384 else
386 rIStream >> nRed;
387 rIStream >> nGreen;
388 rIStream >> nBlue;
391 rColor.mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
393 else
395 static ColorData aColAry[] =
397 COL_BLACK, // COL_BLACK
398 COL_BLUE, // COL_BLUE
399 COL_GREEN, // COL_GREEN
400 COL_CYAN, // COL_CYAN
401 COL_RED, // COL_RED
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];
432 else
433 rColor.mnColor = COL_BLACK;
436 return rIStream;
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];
456 USHORT i = 0;
458 if ( nRed & 0x00FF )
460 nColorName |= COL_RED_2B;
461 cAry[i] = (unsigned char)(nRed & 0xFF);
462 i++;
463 cAry[i] = (unsigned char)((nRed >> 8) & 0xFF);
464 i++;
466 else if ( nRed & 0xFF00 )
468 nColorName |= COL_RED_1B;
469 cAry[i] = (unsigned char)((nRed >> 8) & 0xFF);
470 i++;
472 if ( nGreen & 0x00FF )
474 nColorName |= COL_GREEN_2B;
475 cAry[i] = (unsigned char)(nGreen & 0xFF);
476 i++;
477 cAry[i] = (unsigned char)((nGreen >> 8) & 0xFF);
478 i++;
480 else if ( nGreen & 0xFF00 )
482 nColorName |= COL_GREEN_1B;
483 cAry[i] = (unsigned char)((nGreen >> 8) & 0xFF);
484 i++;
486 if ( nBlue & 0x00FF )
488 nColorName |= COL_BLUE_2B;
489 cAry[i] = (unsigned char)(nBlue & 0xFF);
490 i++;
491 cAry[i] = (unsigned char)((nBlue >> 8) & 0xFF);
492 i++;
494 else if ( nBlue & 0xFF00 )
496 nColorName |= COL_BLUE_1B;
497 cAry[i] = (unsigned char)((nBlue >> 8) & 0xFF);
498 i++;
501 rOStream << nColorName;
502 rOStream.Write( cAry, i );
504 else
506 rOStream << nColorName;
507 rOStream << nRed;
508 rOStream << nGreen;
509 rOStream << nBlue;
512 return rOStream;