Branch data Line data Source code
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 : :
20 : : #include <stdlib.h>
21 : :
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>
28 : : #include <tools/rc.h>
29 : :
30 : 315 : static inline long _FRound( double fVal )
31 : : {
32 [ + - ]: 315 : return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
33 : : }
34 : :
35 : 695 : Color::Color( const ResId& rResId )
36 : : {
37 : 695 : rResId.SetRT( RSC_COLOR );
38 : 695 : ResMgr* pResMgr = rResId.GetResMgr();
39 [ + - ][ + - ]: 695 : if ( pResMgr && pResMgr->GetResource( rResId ) )
[ + - ]
40 : : {
41 : : // Header ueberspringen
42 : 695 : pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
43 : :
44 : : // Daten laden
45 : 695 : sal_uInt16 nRed = pResMgr->ReadShort();
46 : 695 : sal_uInt16 nGreen = pResMgr->ReadShort();
47 : 695 : sal_uInt16 nBlue = pResMgr->ReadShort();
48 : : // one more historical sal_uIntPtr
49 : 695 : pResMgr->ReadLong();
50 : :
51 : : // RGB-Farbe
52 : 695 : mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
53 : : }
54 : : else
55 : : {
56 : 0 : mnColor = RGB_COLORDATA( 0, 0, 0 );
57 : : }
58 : 695 : }
59 : :
60 : 315 : sal_uInt8 Color::GetColorError( const Color& rCompareColor ) const
61 : : {
62 : 315 : const long nErrAbs = labs( (long) rCompareColor.GetRed() - GetRed() ) +
63 : 315 : labs( (long) rCompareColor.GetGreen() - GetGreen() ) +
64 : 315 : labs( (long) rCompareColor.GetBlue() - GetBlue() );
65 : :
66 : 315 : return (sal_uInt8) _FRound( nErrAbs * 0.3333333333 );
67 : : }
68 : :
69 : 5748 : void Color::IncreaseLuminance( sal_uInt8 cLumInc )
70 : : {
71 [ + - ]: 5748 : SetRed( (sal_uInt8) SAL_BOUND( (long) COLORDATA_RED( mnColor ) + cLumInc, 0L, 255L ) );
72 [ + - ]: 5748 : SetGreen( (sal_uInt8) SAL_BOUND( (long) COLORDATA_GREEN( mnColor ) + cLumInc, 0L, 255L ) );
73 [ + - ]: 5748 : SetBlue( (sal_uInt8) SAL_BOUND( (long) COLORDATA_BLUE( mnColor ) + cLumInc, 0L, 255L ) );
74 : 5748 : }
75 : :
76 : 2088 : void Color::DecreaseLuminance( sal_uInt8 cLumDec )
77 : : {
78 [ + + ]: 2088 : SetRed( (sal_uInt8) SAL_BOUND( (long) COLORDATA_RED( mnColor ) - cLumDec, 0L, 255L ) );
79 [ + + ]: 2088 : SetGreen( (sal_uInt8) SAL_BOUND( (long) COLORDATA_GREEN( mnColor ) - cLumDec, 0L, 255L ) );
80 [ + + ]: 2088 : SetBlue( (sal_uInt8) SAL_BOUND( (long) COLORDATA_BLUE( mnColor ) - cLumDec, 0L, 255L ) );
81 : 2088 : }
82 : :
83 : 0 : void Color::DecreaseContrast( sal_uInt8 cContDec )
84 : : {
85 [ # # ]: 0 : if( cContDec )
86 : : {
87 : 0 : const double fM = ( 128.0 - 0.4985 * cContDec ) / 128.0;
88 : 0 : const double fOff = 128.0 - fM * 128.0;
89 : :
90 [ # # ][ # # ]: 0 : SetRed( (sal_uInt8) SAL_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
91 [ # # ][ # # ]: 0 : SetGreen( (sal_uInt8) SAL_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
92 [ # # ][ # # ]: 0 : SetBlue( (sal_uInt8) SAL_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
93 : : }
94 : 0 : }
95 : :
96 : 0 : void Color::Invert()
97 : : {
98 : 0 : SetRed( ~COLORDATA_RED( mnColor ) );
99 : 0 : SetGreen( ~COLORDATA_GREEN( mnColor ) );
100 : 0 : SetBlue( ~COLORDATA_BLUE( mnColor ) );
101 : 0 : }
102 : :
103 : 190114 : sal_Bool Color::IsDark() const
104 : : {
105 : 190114 : return GetLuminance() <= 38;
106 : : }
107 : :
108 : 315758 : sal_Bool Color::IsBright() const
109 : : {
110 : 315758 : return GetLuminance() >= 245;
111 : : }
112 : :
113 : : // color space conversion
114 : :
115 : 178622 : void Color::RGBtoHSB( sal_uInt16& nHue, sal_uInt16& nSat, sal_uInt16& nBri ) const
116 : : {
117 : : sal_uInt8 c[3];
118 : : sal_uInt8 cMax, cMin;
119 : :
120 : 178622 : c[0] = GetRed();
121 : 178622 : c[1] = GetGreen();
122 : 178622 : c[2] = GetBlue();
123 : :
124 : 178622 : cMax = c[0];
125 [ - + ]: 178622 : if( c[1] > cMax )
126 : 0 : cMax = c[1];
127 [ + + ]: 178622 : if( c[2] > cMax )
128 : 650 : cMax = c[2];
129 : :
130 : : // Brightness = max(R, G, B);
131 : 178622 : nBri = cMax * 100 / 255;
132 : :
133 : 178622 : cMin = c[0];
134 [ - + ]: 178622 : if( c[1] < cMin )
135 : 0 : cMin = c[1];
136 [ - + ]: 178622 : if( c[2] < cMin )
137 : 0 : cMin = c[2];
138 : :
139 : 178622 : sal_uInt8 cDelta = cMax - cMin;
140 : :
141 : : // Saturation = max - min / max
142 [ + - ]: 178622 : if( nBri > 0 )
143 : 178622 : nSat = cDelta * 100 / cMax;
144 : : else
145 : 0 : nSat = 0;
146 : :
147 [ + + ]: 178622 : if( nSat == 0 )
148 : 177972 : nHue = 0; // Default = undefined
149 : : else
150 : : {
151 : 650 : double dHue = 0.0;
152 : :
153 [ - + ]: 650 : if( c[0] == cMax )
154 : : {
155 : 0 : dHue = (double)( c[1] - c[2] ) / (double)cDelta;
156 : : }
157 [ - + ]: 650 : else if( c[1] == cMax )
158 : : {
159 : 0 : dHue = 2.0 + (double)( c[2] - c[0] ) / (double)cDelta;
160 : : }
161 [ + - ]: 650 : else if ( c[2] == cMax )
162 : : {
163 : 650 : dHue = 4.0 + (double)( c[0] - c[1] ) / (double)cDelta;
164 : : }
165 : 650 : dHue *= 60.0;
166 : :
167 [ - + ]: 650 : if( dHue < 0.0 )
168 : 0 : dHue += 360.0;
169 : :
170 : 650 : nHue = (sal_uInt16) dHue;
171 : : }
172 : 178622 : }
173 : :
174 : 178622 : ColorData Color::HSBtoRGB( sal_uInt16 nHue, sal_uInt16 nSat, sal_uInt16 nBri )
175 : : {
176 : 178622 : sal_uInt8 cR=0,cG=0,cB=0;
177 : 178622 : sal_uInt8 nB = (sal_uInt8) ( nBri * 255 / 100 );
178 : :
179 [ + + ]: 178622 : if( nSat == 0 )
180 : : {
181 : 177972 : cR = nB;
182 : 177972 : cG = nB;
183 : 177972 : cB = nB;
184 : : }
185 : : else
186 : : {
187 : 650 : double dH = nHue;
188 : : double f;
189 : : sal_uInt16 n;
190 [ - + ]: 650 : if( dH == 360.0 )
191 : 0 : dH = 0.0;
192 : :
193 : 650 : dH /= 60.0;
194 : 650 : n = (sal_uInt16) dH;
195 : 650 : f = dH - n;
196 : :
197 : 650 : sal_uInt8 a = (sal_uInt8) ( nB * ( 100 - nSat ) / 100 );
198 : 650 : sal_uInt8 b = (sal_uInt8) ( nB * ( 100 - ( (double)nSat * f ) ) / 100 );
199 : 650 : sal_uInt8 c = (sal_uInt8) ( nB * ( 100 - ( (double)nSat * ( 1.0 - f ) ) ) / 100 );
200 : :
201 [ - - - - : 650 : switch( n )
+ - - ]
202 : : {
203 : 0 : case 0: cR = nB; cG = c; cB = a; break;
204 : 0 : case 1: cR = b; cG = nB; cB = a; break;
205 : 0 : case 2: cR = a; cG = nB; cB = c; break;
206 : 0 : case 3: cR = a; cG = b; cB = nB; break;
207 : 650 : case 4: cR = c; cG = a; cB = nB; break;
208 : 0 : case 5: cR = nB; cG = a; cB = b; break;
209 : : }
210 : : }
211 : :
212 : 178622 : return RGB_COLORDATA( cR, cG, cB );
213 : : }
214 : :
215 : 222790 : SvStream& Color::Read( SvStream& rIStm, sal_Bool bNewFormat )
216 : : {
217 [ + - ]: 222790 : if ( bNewFormat )
218 : 222790 : rIStm >> mnColor;
219 : : else
220 : 0 : rIStm >> *this;
221 : :
222 : 222790 : return rIStm;
223 : : }
224 : :
225 : 291480 : SvStream& Color::Write( SvStream& rOStm, sal_Bool bNewFormat )
226 : : {
227 [ + - ]: 291480 : if ( bNewFormat )
228 : 291480 : rOStm << mnColor;
229 : : else
230 : 0 : rOStm << *this;
231 : :
232 : 291480 : return rOStm;
233 : : }
234 : :
235 : : #define COL_NAME_USER ((sal_uInt16)0x8000)
236 : :
237 : 1588 : SvStream& operator>>( SvStream& rIStream, Color& rColor )
238 : : {
239 : : DBG_ASSERTWARNING( rIStream.GetVersion(), "Color::>> - Solar-Version not set on rIStream" );
240 : :
241 : : sal_uInt16 nColorName;
242 : :
243 [ + - ]: 1588 : rIStream >> nColorName;
244 : :
245 [ + - ]: 1588 : if ( nColorName & COL_NAME_USER )
246 : : {
247 : : sal_uInt16 nRed;
248 : : sal_uInt16 nGreen;
249 : : sal_uInt16 nBlue;
250 : :
251 [ + - ]: 1588 : rIStream >> nRed;
252 [ + - ]: 1588 : rIStream >> nGreen;
253 [ + - ]: 1588 : rIStream >> nBlue;
254 : :
255 : 1588 : rColor.mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
256 : : }
257 : : else
258 : : {
259 : : static ColorData aColAry[] =
260 : : {
261 : : COL_BLACK, // COL_BLACK
262 : : COL_BLUE, // COL_BLUE
263 : : COL_GREEN, // COL_GREEN
264 : : COL_CYAN, // COL_CYAN
265 : : COL_RED, // COL_RED
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
292 : : };
293 : :
294 [ # # ]: 0 : if ( nColorName < (sizeof( aColAry )/sizeof(ColorData)) )
295 : 0 : rColor.mnColor = aColAry[nColorName];
296 : : else
297 : 0 : rColor.mnColor = COL_BLACK;
298 : : }
299 : :
300 : 1588 : return rIStream;
301 : : }
302 : :
303 : 8846 : SvStream& operator<<( SvStream& rOStream, const Color& rColor )
304 : : {
305 : : DBG_ASSERTWARNING( rOStream.GetVersion(), "Color::<< - Solar-Version not set on rOStream" );
306 : :
307 : 8846 : sal_uInt16 nColorName = COL_NAME_USER;
308 : 8846 : sal_uInt16 nRed = rColor.GetRed();
309 : 8846 : sal_uInt16 nGreen = rColor.GetGreen();
310 : 8846 : sal_uInt16 nBlue = rColor.GetBlue();
311 : 8846 : nRed = (nRed<<8) + nRed;
312 : 8846 : nGreen = (nGreen<<8) + nGreen;
313 : 8846 : nBlue = (nBlue<<8) + nBlue;
314 : :
315 : 8846 : rOStream << nColorName;
316 : 8846 : rOStream << nRed;
317 : 8846 : rOStream << nGreen;
318 : 8846 : rOStream << nBlue;
319 : :
320 : 8846 : return rOStream;
321 : : }
322 : :
323 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|