PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/tools/source/generic/color.cxx

https://bitbucket.org/mst/ooo340
C++ | 510 lines | 386 code | 70 blank | 54 comment | 59 complexity | 8d3dd526e07998a1b2a147e20d83f2d4 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-3.0, AGPL-1.0, BSD-3-Clause-No-Nuclear-License-2014, GPL-3.0, GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. /*************************************************************************
  2. *
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * Copyright 2000, 2010 Oracle and/or its affiliates.
  6. *
  7. * OpenOffice.org - a multi-platform office productivity suite
  8. *
  9. * This file is part of OpenOffice.org.
  10. *
  11. * OpenOffice.org is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU Lesser General Public License version 3
  13. * only, as published by the Free Software Foundation.
  14. *
  15. * OpenOffice.org is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU Lesser General Public License version 3 for more details
  19. * (a copy is included in the LICENSE file that accompanied this code).
  20. *
  21. * You should have received a copy of the GNU Lesser General Public License
  22. * version 3 along with OpenOffice.org. If not, see
  23. * <http://www.openoffice.org/license.html>
  24. * for a copy of the LGPLv3 License.
  25. *
  26. ************************************************************************/
  27. // MARKER(update_precomp.py): autogen include statement, do not remove
  28. #include "precompiled_tools.hxx"
  29. #include <stdlib.h>
  30. #include <vos/macros.hxx>
  31. #include <tools/color.hxx>
  32. #include <tools/debug.hxx>
  33. #include <tools/stream.hxx>
  34. #include <tools/rc.hxx>
  35. #include <tools/rcid.h>
  36. #include <tools/resid.hxx>
  37. #ifndef _SV_RC_H
  38. #include <tools/rc.h>
  39. #endif
  40. // -----------
  41. // - Inlines -
  42. // -----------
  43. static inline long _FRound( double fVal )
  44. {
  45. return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
  46. }
  47. // ---------
  48. // - Color -
  49. // ---------
  50. Color::Color( const ResId& rResId )
  51. {
  52. rResId.SetRT( RSC_COLOR );
  53. ResMgr* pResMgr = rResId.GetResMgr();
  54. if ( pResMgr && pResMgr->GetResource( rResId ) )
  55. {
  56. // Header ueberspringen
  57. pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
  58. // Daten laden
  59. USHORT nRed = pResMgr->ReadShort();
  60. USHORT nGreen = pResMgr->ReadShort();
  61. USHORT nBlue = pResMgr->ReadShort();
  62. // one more historical ULONG
  63. pResMgr->ReadLong();
  64. // RGB-Farbe
  65. mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
  66. }
  67. else
  68. {
  69. mnColor = RGB_COLORDATA( 0, 0, 0 );
  70. }
  71. }
  72. UINT8 Color::GetColorError( const Color& rCompareColor ) const
  73. {
  74. const long nErrAbs = labs( (long) rCompareColor.GetRed() - GetRed() ) +
  75. labs( (long) rCompareColor.GetGreen() - GetGreen() ) +
  76. labs( (long) rCompareColor.GetBlue() - GetBlue() );
  77. return (UINT8) _FRound( nErrAbs * 0.3333333333 );
  78. }
  79. // -----------------------------------------------------------------------
  80. void Color::IncreaseLuminance( UINT8 cLumInc )
  81. {
  82. SetRed( (UINT8) VOS_BOUND( (long) COLORDATA_RED( mnColor ) + cLumInc, 0L, 255L ) );
  83. SetGreen( (UINT8) VOS_BOUND( (long) COLORDATA_GREEN( mnColor ) + cLumInc, 0L, 255L ) );
  84. SetBlue( (UINT8) VOS_BOUND( (long) COLORDATA_BLUE( mnColor ) + cLumInc, 0L, 255L ) );
  85. }
  86. // -----------------------------------------------------------------------
  87. void Color::DecreaseLuminance( UINT8 cLumDec )
  88. {
  89. SetRed( (UINT8) VOS_BOUND( (long) COLORDATA_RED( mnColor ) - cLumDec, 0L, 255L ) );
  90. SetGreen( (UINT8) VOS_BOUND( (long) COLORDATA_GREEN( mnColor ) - cLumDec, 0L, 255L ) );
  91. SetBlue( (UINT8) VOS_BOUND( (long) COLORDATA_BLUE( mnColor ) - cLumDec, 0L, 255L ) );
  92. }
  93. // -----------------------------------------------------------------------
  94. void Color::IncreaseContrast( UINT8 cContInc )
  95. {
  96. if( cContInc)
  97. {
  98. const double fM = 128.0 / ( 128.0 - 0.4985 * cContInc );
  99. const double fOff = 128.0 - fM * 128.0;
  100. SetRed( (UINT8) VOS_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
  101. SetGreen( (UINT8) VOS_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
  102. SetBlue( (UINT8) VOS_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
  103. }
  104. }
  105. // -----------------------------------------------------------------------
  106. void Color::DecreaseContrast( UINT8 cContDec )
  107. {
  108. if( cContDec )
  109. {
  110. const double fM = ( 128.0 - 0.4985 * cContDec ) / 128.0;
  111. const double fOff = 128.0 - fM * 128.0;
  112. SetRed( (UINT8) VOS_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
  113. SetGreen( (UINT8) VOS_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
  114. SetBlue( (UINT8) VOS_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
  115. }
  116. }
  117. // -----------------------------------------------------------------------
  118. void Color::Invert()
  119. {
  120. SetRed( ~COLORDATA_RED( mnColor ) );
  121. SetGreen( ~COLORDATA_GREEN( mnColor ) );
  122. SetBlue( ~COLORDATA_BLUE( mnColor ) );
  123. }
  124. // -----------------------------------------------------------------------
  125. BOOL Color::IsDark() const
  126. {
  127. return GetLuminance() <= 38;
  128. }
  129. // -----------------------------------------------------------------------
  130. BOOL Color::IsBright() const
  131. {
  132. return GetLuminance() >= 245;
  133. }
  134. // -----------------------------------------------------------------------
  135. // color space conversion
  136. // -----------------------------------------------------------------------
  137. void Color::RGBtoHSB( USHORT& nHue, USHORT& nSat, USHORT& nBri ) const
  138. {
  139. UINT8 c[3];
  140. UINT8 cMax, cMin;
  141. c[0] = GetRed();
  142. c[1] = GetGreen();
  143. c[2] = GetBlue();
  144. cMax = c[0];
  145. if( c[1] > cMax )
  146. cMax = c[1];
  147. if( c[2] > cMax )
  148. cMax = c[2];
  149. // Brightness = max(R, G, B);
  150. nBri = cMax * 100 / 255;
  151. cMin = c[0];
  152. if( c[1] < cMin )
  153. cMin = c[1];
  154. if( c[2] < cMin )
  155. cMin = c[2];
  156. UINT8 cDelta = cMax - cMin;
  157. // Saturation = max - min / max
  158. if( nBri > 0 )
  159. nSat = cDelta * 100 / cMax;
  160. else
  161. nSat = 0;
  162. if( nSat == 0 )
  163. nHue = 0; // Default = undefined
  164. else
  165. {
  166. double dHue = 0.0;
  167. if( c[0] == cMax )
  168. {
  169. dHue = (double)( c[1] - c[2] ) / (double)cDelta;
  170. }
  171. else if( c[1] == cMax )
  172. {
  173. dHue = 2.0 + (double)( c[2] - c[0] ) / (double)cDelta;
  174. }
  175. else if ( c[2] == cMax )
  176. {
  177. dHue = 4.0 + (double)( c[0] - c[1] ) / (double)cDelta;
  178. }
  179. dHue *= 60.0;
  180. if( dHue < 0.0 )
  181. dHue += 360.0;
  182. nHue = (UINT16) dHue;
  183. }
  184. }
  185. ColorData Color::HSBtoRGB( USHORT nHue, USHORT nSat, USHORT nBri )
  186. {
  187. UINT8 cR=0,cG=0,cB=0;
  188. UINT8 nB = (UINT8) ( nBri * 255 / 100 );
  189. if( nSat == 0 )
  190. {
  191. cR = nB;
  192. cG = nB;
  193. cB = nB;
  194. }
  195. else
  196. {
  197. double dH = nHue;
  198. double f;
  199. UINT16 n;
  200. if( dH == 360.0 )
  201. dH = 0.0;
  202. dH /= 60.0;
  203. n = (UINT16) dH;
  204. f = dH - n;
  205. UINT8 a = (UINT8) ( nB * ( 100 - nSat ) / 100 );
  206. UINT8 b = (UINT8) ( nB * ( 100 - ( (double)nSat * f + 0.5 ) ) / 100 );
  207. UINT8 c = (UINT8) ( nB * ( 100 - ( (double)nSat * ( 1.0 - f ) + 0.5 ) ) / 100 );
  208. switch( n )
  209. {
  210. case 0: cR = nB; cG = c; cB = a; break;
  211. case 1: cR = b; cG = nB; cB = a; break;
  212. case 2: cR = a; cG = nB; cB = c; break;
  213. case 3: cR = a; cG = b; cB = nB; break;
  214. case 4: cR = c; cG = a; cB = nB; break;
  215. case 5: cR = nB; cG = a; cB = b; break;
  216. }
  217. }
  218. return RGB_COLORDATA( cR, cG, cB );
  219. }
  220. // -----------------------------------------------------------------------
  221. SvStream& Color::Read( SvStream& rIStm, BOOL bNewFormat )
  222. {
  223. if ( bNewFormat )
  224. rIStm >> mnColor;
  225. else
  226. rIStm >> *this;
  227. return rIStm;
  228. }
  229. // -----------------------------------------------------------------------
  230. SvStream& Color::Write( SvStream& rOStm, BOOL bNewFormat )
  231. {
  232. if ( bNewFormat )
  233. rOStm << mnColor;
  234. else
  235. rOStm << *this;
  236. return rOStm;
  237. }
  238. // -----------------------------------------------------------------------
  239. #define COL_NAME_USER ((USHORT)0x8000)
  240. #define COL_RED_1B ((USHORT)0x0001)
  241. #define COL_RED_2B ((USHORT)0x0002)
  242. #define COL_GREEN_1B ((USHORT)0x0010)
  243. #define COL_GREEN_2B ((USHORT)0x0020)
  244. #define COL_BLUE_1B ((USHORT)0x0100)
  245. #define COL_BLUE_2B ((USHORT)0x0200)
  246. // -----------------------------------------------------------------------
  247. SvStream& operator>>( SvStream& rIStream, Color& rColor )
  248. {
  249. DBG_ASSERTWARNING( rIStream.GetVersion(), "Color::>> - Solar-Version not set on rIStream" );
  250. USHORT nColorName;
  251. USHORT nRed;
  252. USHORT nGreen;
  253. USHORT nBlue;
  254. rIStream >> nColorName;
  255. if ( nColorName & COL_NAME_USER )
  256. {
  257. if ( rIStream.GetCompressMode() == COMPRESSMODE_FULL )
  258. {
  259. unsigned char cAry[6];
  260. USHORT i = 0;
  261. nRed = 0;
  262. nGreen = 0;
  263. nBlue = 0;
  264. if ( nColorName & COL_RED_2B )
  265. i += 2;
  266. else if ( nColorName & COL_RED_1B )
  267. i++;
  268. if ( nColorName & COL_GREEN_2B )
  269. i += 2;
  270. else if ( nColorName & COL_GREEN_1B )
  271. i++;
  272. if ( nColorName & COL_BLUE_2B )
  273. i += 2;
  274. else if ( nColorName & COL_BLUE_1B )
  275. i++;
  276. rIStream.Read( cAry, i );
  277. i = 0;
  278. if ( nColorName & COL_RED_2B )
  279. {
  280. nRed = cAry[i];
  281. nRed <<= 8;
  282. i++;
  283. nRed |= cAry[i];
  284. i++;
  285. }
  286. else if ( nColorName & COL_RED_1B )
  287. {
  288. nRed = cAry[i];
  289. nRed <<= 8;
  290. i++;
  291. }
  292. if ( nColorName & COL_GREEN_2B )
  293. {
  294. nGreen = cAry[i];
  295. nGreen <<= 8;
  296. i++;
  297. nGreen |= cAry[i];
  298. i++;
  299. }
  300. else if ( nColorName & COL_GREEN_1B )
  301. {
  302. nGreen = cAry[i];
  303. nGreen <<= 8;
  304. i++;
  305. }
  306. if ( nColorName & COL_BLUE_2B )
  307. {
  308. nBlue = cAry[i];
  309. nBlue <<= 8;
  310. i++;
  311. nBlue |= cAry[i];
  312. i++;
  313. }
  314. else if ( nColorName & COL_BLUE_1B )
  315. {
  316. nBlue = cAry[i];
  317. nBlue <<= 8;
  318. i++;
  319. }
  320. }
  321. else
  322. {
  323. rIStream >> nRed;
  324. rIStream >> nGreen;
  325. rIStream >> nBlue;
  326. }
  327. rColor.mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
  328. }
  329. else
  330. {
  331. static ColorData aColAry[] =
  332. {
  333. COL_BLACK, // COL_BLACK
  334. COL_BLUE, // COL_BLUE
  335. COL_GREEN, // COL_GREEN
  336. COL_CYAN, // COL_CYAN
  337. COL_RED, // COL_RED
  338. COL_MAGENTA, // COL_MAGENTA
  339. COL_BROWN, // COL_BROWN
  340. COL_GRAY, // COL_GRAY
  341. COL_LIGHTGRAY, // COL_LIGHTGRAY
  342. COL_LIGHTBLUE, // COL_LIGHTBLUE
  343. COL_LIGHTGREEN, // COL_LIGHTGREEN
  344. COL_LIGHTCYAN, // COL_LIGHTCYAN
  345. COL_LIGHTRED, // COL_LIGHTRED
  346. COL_LIGHTMAGENTA, // COL_LIGHTMAGENTA
  347. COL_YELLOW, // COL_YELLOW
  348. COL_WHITE, // COL_WHITE
  349. COL_WHITE, // COL_MENUBAR
  350. COL_BLACK, // COL_MENUBARTEXT
  351. COL_WHITE, // COL_POPUPMENU
  352. COL_BLACK, // COL_POPUPMENUTEXT
  353. COL_BLACK, // COL_WINDOWTEXT
  354. COL_WHITE, // COL_WINDOWWORKSPACE
  355. COL_BLACK, // COL_HIGHLIGHT
  356. COL_WHITE, // COL_HIGHLIGHTTEXT
  357. COL_BLACK, // COL_3DTEXT
  358. COL_LIGHTGRAY, // COL_3DFACE
  359. COL_WHITE, // COL_3DLIGHT
  360. COL_GRAY, // COL_3DSHADOW
  361. COL_LIGHTGRAY, // COL_SCROLLBAR
  362. COL_WHITE, // COL_FIELD
  363. COL_BLACK // COL_FIELDTEXT
  364. };
  365. if ( nColorName < (sizeof( aColAry )/sizeof(ColorData)) )
  366. rColor.mnColor = aColAry[nColorName];
  367. else
  368. rColor.mnColor = COL_BLACK;
  369. }
  370. return rIStream;
  371. }
  372. // -----------------------------------------------------------------------
  373. SvStream& operator<<( SvStream& rOStream, const Color& rColor )
  374. {
  375. DBG_ASSERTWARNING( rOStream.GetVersion(), "Color::<< - Solar-Version not set on rOStream" );
  376. USHORT nColorName = COL_NAME_USER;
  377. USHORT nRed = rColor.GetRed();
  378. USHORT nGreen = rColor.GetGreen();
  379. USHORT nBlue = rColor.GetBlue();
  380. nRed = (nRed<<8) + nRed;
  381. nGreen = (nGreen<<8) + nGreen;
  382. nBlue = (nBlue<<8) + nBlue;
  383. if ( rOStream.GetCompressMode() == COMPRESSMODE_FULL )
  384. {
  385. unsigned char cAry[6];
  386. USHORT i = 0;
  387. if ( nRed & 0x00FF )
  388. {
  389. nColorName |= COL_RED_2B;
  390. cAry[i] = (unsigned char)(nRed & 0xFF);
  391. i++;
  392. cAry[i] = (unsigned char)((nRed >> 8) & 0xFF);
  393. i++;
  394. }
  395. else if ( nRed & 0xFF00 )
  396. {
  397. nColorName |= COL_RED_1B;
  398. cAry[i] = (unsigned char)((nRed >> 8) & 0xFF);
  399. i++;
  400. }
  401. if ( nGreen & 0x00FF )
  402. {
  403. nColorName |= COL_GREEN_2B;
  404. cAry[i] = (unsigned char)(nGreen & 0xFF);
  405. i++;
  406. cAry[i] = (unsigned char)((nGreen >> 8) & 0xFF);
  407. i++;
  408. }
  409. else if ( nGreen & 0xFF00 )
  410. {
  411. nColorName |= COL_GREEN_1B;
  412. cAry[i] = (unsigned char)((nGreen >> 8) & 0xFF);
  413. i++;
  414. }
  415. if ( nBlue & 0x00FF )
  416. {
  417. nColorName |= COL_BLUE_2B;
  418. cAry[i] = (unsigned char)(nBlue & 0xFF);
  419. i++;
  420. cAry[i] = (unsigned char)((nBlue >> 8) & 0xFF);
  421. i++;
  422. }
  423. else if ( nBlue & 0xFF00 )
  424. {
  425. nColorName |= COL_BLUE_1B;
  426. cAry[i] = (unsigned char)((nBlue >> 8) & 0xFF);
  427. i++;
  428. }
  429. rOStream << nColorName;
  430. rOStream.Write( cAry, i );
  431. }
  432. else
  433. {
  434. rOStream << nColorName;
  435. rOStream << nRed;
  436. rOStream << nGreen;
  437. rOStream << nBlue;
  438. }
  439. return rOStream;
  440. }