LCOV - code coverage report
Current view: top level - tools/source/generic - color.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 109 141 77.3 %
Date: 2015-06-13 12:38:46 Functions: 14 16 87.5 %
Legend: Lines: hit not hit

          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 <sal/config.h>
      21             : 
      22             : #include <sstream>
      23             : #include <stdlib.h>
      24             : 
      25             : #include <tools/color.hxx>
      26             : #include <tools/debug.hxx>
      27             : #include <tools/stream.hxx>
      28             : #include <tools/rc.hxx>
      29             : #include <tools/rcid.h>
      30             : #include <tools/resid.hxx>
      31             : #include <tools/rc.h>
      32             : #include <tools/helpers.hxx>
      33             : #include <basegfx/color/bcolortools.hxx>
      34             : 
      35         513 : static inline long _FRound( double fVal )
      36             : {
      37         513 :     return( fVal > 0.0 ? (long) ( fVal + 0.5 ) : -(long) ( -fVal + 0.5 ) );
      38             : }
      39             : 
      40         124 : Color::Color( const ResId& rResId )
      41             : {
      42         124 :     rResId.SetRT( RSC_COLOR );
      43         124 :     ResMgr* pResMgr = rResId.GetResMgr();
      44         124 :     if ( pResMgr && pResMgr->GetResource( rResId ) )
      45             :     {
      46             :         // Header ueberspringen
      47         124 :         pResMgr->Increment( sizeof( RSHEADER_TYPE ) );
      48             : 
      49             :         // Daten laden
      50         124 :         sal_uInt16 nRed     = pResMgr->ReadShort();
      51         124 :         sal_uInt16 nGreen   = pResMgr->ReadShort();
      52         124 :         sal_uInt16 nBlue    = pResMgr->ReadShort();
      53             :         // one more historical sal_uIntPtr
      54         124 :         pResMgr->ReadLong();
      55             : 
      56             :         // RGB-Farbe
      57         124 :         mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
      58             :     }
      59             :     else
      60             :     {
      61           0 :         mnColor = RGB_COLORDATA( 0, 0, 0 );
      62             :     }
      63         124 : }
      64             : 
      65         513 : sal_uInt8 Color::GetColorError( const Color& rCompareColor ) const
      66             : {
      67        1026 :     const long nErrAbs = labs( (long) rCompareColor.GetRed() - GetRed() ) +
      68         513 :                          labs( (long) rCompareColor.GetGreen() - GetGreen() ) +
      69         513 :                          labs( (long) rCompareColor.GetBlue() - GetBlue() );
      70             : 
      71         513 :     return (sal_uInt8) _FRound( nErrAbs * 0.3333333333 );
      72             : }
      73             : 
      74        6461 : void Color::IncreaseLuminance( sal_uInt8 cLumInc )
      75             : {
      76        6461 :     SetRed( (sal_uInt8) SAL_BOUND( (long) COLORDATA_RED( mnColor ) + cLumInc, 0L, 255L ) );
      77        6461 :     SetGreen( (sal_uInt8) SAL_BOUND( (long) COLORDATA_GREEN( mnColor ) + cLumInc, 0L, 255L ) );
      78        6461 :     SetBlue( (sal_uInt8) SAL_BOUND( (long) COLORDATA_BLUE( mnColor ) + cLumInc, 0L, 255L ) );
      79        6461 : }
      80             : 
      81        9610 : void Color::DecreaseLuminance( sal_uInt8 cLumDec )
      82             : {
      83        9610 :     SetRed( (sal_uInt8) SAL_BOUND( (long) COLORDATA_RED( mnColor ) - cLumDec, 0L, 255L ) );
      84        9610 :     SetGreen( (sal_uInt8) SAL_BOUND( (long) COLORDATA_GREEN( mnColor ) - cLumDec, 0L, 255L ) );
      85        9610 :     SetBlue( (sal_uInt8) SAL_BOUND( (long) COLORDATA_BLUE( mnColor ) - cLumDec, 0L, 255L ) );
      86        9610 : }
      87             : 
      88           0 : void Color::DecreaseContrast( sal_uInt8 cContDec )
      89             : {
      90           0 :     if( cContDec )
      91             :     {
      92           0 :         const double fM = ( 128.0 - 0.4985 * cContDec ) / 128.0;
      93           0 :         const double fOff = 128.0 - fM * 128.0;
      94             : 
      95           0 :         SetRed( (sal_uInt8) SAL_BOUND( _FRound( COLORDATA_RED( mnColor ) * fM + fOff ), 0L, 255L ) );
      96           0 :         SetGreen( (sal_uInt8) SAL_BOUND( _FRound( COLORDATA_GREEN( mnColor ) * fM + fOff ), 0L, 255L ) );
      97           0 :         SetBlue( (sal_uInt8) SAL_BOUND( _FRound( COLORDATA_BLUE( mnColor ) * fM + fOff ), 0L, 255L ) );
      98             :     }
      99           0 : }
     100             : 
     101           0 : void Color::Invert()
     102             : {
     103           0 :     SetRed( ~COLORDATA_RED( mnColor ) );
     104           0 :     SetGreen( ~COLORDATA_GREEN( mnColor ) );
     105           0 :     SetBlue( ~COLORDATA_BLUE( mnColor ) );
     106           0 : }
     107             : 
     108       99414 : bool Color::IsDark() const
     109             : {
     110       99414 :     return GetLuminance() <= 60;
     111             : }
     112             : 
     113      148444 : bool Color::IsBright() const
     114             : {
     115      148444 :     return GetLuminance() >= 245;
     116             : }
     117             : 
     118             : // color space conversion
     119             : 
     120      102204 : void Color::RGBtoHSB( sal_uInt16& nHue, sal_uInt16& nSat, sal_uInt16& nBri ) const
     121             : {
     122             :     sal_uInt8 c[3];
     123             :     sal_uInt8 cMax, cMin;
     124             : 
     125      102204 :     c[0] = GetRed();
     126      102204 :     c[1] = GetGreen();
     127      102204 :     c[2] = GetBlue();
     128             : 
     129      102204 :     cMax = c[0];
     130      102204 :     if( c[1] > cMax )
     131           0 :         cMax = c[1];
     132      102204 :     if( c[2] > cMax )
     133         384 :         cMax = c[2];
     134             : 
     135             :     // Brightness = max(R, G, B);
     136      102204 :     nBri = cMax * 100 / 255;
     137             : 
     138      102204 :     cMin = c[0];
     139      102204 :     if( c[1] < cMin )
     140           0 :         cMin = c[1];
     141      102204 :     if( c[2] < cMin )
     142           0 :         cMin = c[2];
     143             : 
     144      102204 :     sal_uInt8 cDelta = cMax - cMin;
     145             : 
     146             :     // Saturation = max - min / max
     147      102204 :     if( nBri > 0 )
     148      102204 :         nSat = cDelta * 100 / cMax;
     149             :     else
     150           0 :         nSat = 0;
     151             : 
     152      102204 :     if( nSat == 0 )
     153      101820 :         nHue = 0; // Default = undefined
     154             :     else
     155             :     {
     156         384 :         double dHue = 0.0;
     157             : 
     158         384 :         if( c[0] == cMax )
     159             :         {
     160           0 :             dHue = (double)( c[1] - c[2] ) / (double)cDelta;
     161             :         }
     162         384 :         else if( c[1] == cMax )
     163             :         {
     164           0 :             dHue = 2.0 + (double)( c[2] - c[0] ) / (double)cDelta;
     165             :         }
     166         384 :         else if ( c[2] == cMax )
     167             :         {
     168         384 :             dHue = 4.0 + (double)( c[0] - c[1] ) / (double)cDelta;
     169             :         }
     170         384 :         dHue *= 60.0;
     171             : 
     172         384 :         if( dHue < 0.0 )
     173           0 :             dHue += 360.0;
     174             : 
     175         384 :         nHue = (sal_uInt16) dHue;
     176             :     }
     177      102204 : }
     178             : 
     179      102204 : ColorData Color::HSBtoRGB( sal_uInt16 nHue, sal_uInt16 nSat, sal_uInt16 nBri )
     180             : {
     181      102204 :     sal_uInt8 cR=0,cG=0,cB=0;
     182      102204 :     sal_uInt8 nB = (sal_uInt8) ( nBri * 255 / 100 );
     183             : 
     184      102204 :     if( nSat == 0 )
     185             :     {
     186      101884 :         cR = nB;
     187      101884 :         cG = nB;
     188      101884 :         cB = nB;
     189             :     }
     190             :     else
     191             :     {
     192         320 :         double dH = nHue;
     193             :         double f;
     194             :         sal_uInt16 n;
     195         320 :         if( dH == 360.0 )
     196           0 :             dH = 0.0;
     197             : 
     198         320 :         dH /= 60.0;
     199         320 :         n = (sal_uInt16) dH;
     200         320 :         f = dH - n;
     201             : 
     202         320 :         sal_uInt8 a = (sal_uInt8) ( nB * ( 100 - nSat ) / 100 );
     203         320 :         sal_uInt8 b = (sal_uInt8) ( nB * ( 100 - ( (double)nSat * f ) ) / 100 );
     204         320 :         sal_uInt8 c = (sal_uInt8) ( nB * ( 100 - ( (double)nSat * ( 1.0 - f ) ) ) / 100 );
     205             : 
     206         320 :         switch( n )
     207             :         {
     208           0 :             case 0: cR = nB;    cG = c;     cB = a;     break;
     209           0 :             case 1: cR = b;     cG = nB;    cB = a;     break;
     210           0 :             case 2: cR = a;     cG = nB;    cB = c;     break;
     211           0 :             case 3: cR = a;     cG = b;     cB = nB;    break;
     212         320 :             case 4: cR = c;     cG = a;     cB = nB;    break;
     213           0 :             case 5: cR = nB;    cG = a;     cB = b;     break;
     214             :         }
     215             :     }
     216             : 
     217      102204 :     return RGB_COLORDATA( cR, cG, cB );
     218             : }
     219             : 
     220       83961 : SvStream& Color::Read( SvStream& rIStm, bool bNewFormat )
     221             : {
     222       83961 :     if ( bNewFormat )
     223       83961 :         rIStm.ReadUInt32( mnColor );
     224             :     else
     225           0 :         ReadColor( rIStm, *this );
     226             : 
     227       83961 :     return rIStm;
     228             : }
     229             : 
     230      110841 : SvStream& Color::Write( SvStream& rOStm, bool bNewFormat )
     231             : {
     232      110841 :     if ( bNewFormat )
     233      110841 :         rOStm.WriteUInt32( mnColor );
     234             :     else
     235           0 :         WriteColor( rOStm, *this );
     236             : 
     237      110841 :     return rOStm;
     238             : }
     239             : 
     240          94 : OUString Color::AsRGBHexString() const
     241             : {
     242          94 :     std::stringstream ss;
     243          94 :     ss << std::hex << std::setfill ('0') << std::setw(6) << GetRGBColor();
     244          94 :     return OUString::createFromAscii(ss.str().c_str());
     245             : }
     246             : 
     247             : #define COL_NAME_USER       ((sal_uInt16)0x8000)
     248             : 
     249        3354 : SvStream& ReadColor( SvStream& rIStream, Color& rColor )
     250             : {
     251             :     DBG_ASSERTWARNING( rIStream.GetVersion(), "Color::>> - Solar-Version not set on rIStream" );
     252             : 
     253             :     sal_uInt16      nColorName;
     254             : 
     255        3354 :     rIStream.ReadUInt16( nColorName );
     256             : 
     257        3354 :     if ( nColorName & COL_NAME_USER )
     258             :     {
     259             :         sal_uInt16 nRed;
     260             :         sal_uInt16 nGreen;
     261             :         sal_uInt16 nBlue;
     262             : 
     263        3354 :         rIStream.ReadUInt16( nRed );
     264        3354 :         rIStream.ReadUInt16( nGreen );
     265        3354 :         rIStream.ReadUInt16( nBlue );
     266             : 
     267        3354 :         rColor.mnColor = RGB_COLORDATA( nRed>>8, nGreen>>8, nBlue>>8 );
     268             :     }
     269             :     else
     270             :     {
     271             :         static const ColorData aColAry[] =
     272             :         {
     273             :             COL_BLACK,                          // COL_BLACK
     274             :             COL_BLUE,                           // COL_BLUE
     275             :             COL_GREEN,                          // COL_GREEN
     276             :             COL_CYAN,                           // COL_CYAN
     277             :             COL_RED,                            // COL_RED
     278             :             COL_MAGENTA,                        // COL_MAGENTA
     279             :             COL_BROWN,                          // COL_BROWN
     280             :             COL_GRAY,                           // COL_GRAY
     281             :             COL_LIGHTGRAY,                      // COL_LIGHTGRAY
     282             :             COL_LIGHTBLUE,                      // COL_LIGHTBLUE
     283             :             COL_LIGHTGREEN,                     // COL_LIGHTGREEN
     284             :             COL_LIGHTCYAN,                      // COL_LIGHTCYAN
     285             :             COL_LIGHTRED,                       // COL_LIGHTRED
     286             :             COL_LIGHTMAGENTA,                   // COL_LIGHTMAGENTA
     287             :             COL_YELLOW,                         // COL_YELLOW
     288             :             COL_WHITE,                          // COL_WHITE
     289             :             COL_WHITE,                          // COL_MENUBAR
     290             :             COL_BLACK,                          // COL_MENUBARTEXT
     291             :             COL_WHITE,                          // COL_POPUPMENU
     292             :             COL_BLACK,                          // COL_POPUPMENUTEXT
     293             :             COL_BLACK,                          // COL_WINDOWTEXT
     294             :             COL_WHITE,                          // COL_WINDOWWORKSPACE
     295             :             COL_BLACK,                          // COL_HIGHLIGHT
     296             :             COL_WHITE,                          // COL_HIGHLIGHTTEXT
     297             :             COL_BLACK,                          // COL_3DTEXT
     298             :             COL_LIGHTGRAY,                      // COL_3DFACE
     299             :             COL_WHITE,                          // COL_3DLIGHT
     300             :             COL_GRAY,                           // COL_3DSHADOW
     301             :             COL_LIGHTGRAY,                      // COL_SCROLLBAR
     302             :             COL_WHITE,                          // COL_FIELD
     303             :             COL_BLACK                           // COL_FIELDTEXT
     304             :         };
     305             : 
     306           0 :         if ( nColorName < (sizeof( aColAry )/sizeof(ColorData)) )
     307           0 :             rColor.mnColor = aColAry[nColorName];
     308             :         else
     309           0 :             rColor.mnColor = COL_BLACK;
     310             :     }
     311             : 
     312        3354 :     return rIStream;
     313             : }
     314             : 
     315        4086 : SvStream& WriteColor( SvStream& rOStream, const Color& rColor )
     316             : {
     317             :     DBG_ASSERTWARNING( rOStream.GetVersion(), "Color::<< - Solar-Version not set on rOStream" );
     318             : 
     319        4086 :     sal_uInt16 nColorName   = COL_NAME_USER;
     320        4086 :     sal_uInt16 nRed         = rColor.GetRed();
     321        4086 :     sal_uInt16 nGreen       = rColor.GetGreen();
     322        4086 :     sal_uInt16 nBlue        = rColor.GetBlue();
     323        4086 :     nRed    = (nRed<<8) + nRed;
     324        4086 :     nGreen  = (nGreen<<8) + nGreen;
     325        4086 :     nBlue   = (nBlue<<8) + nBlue;
     326             : 
     327        4086 :     rOStream.WriteUInt16( nColorName );
     328        4086 :     rOStream.WriteUInt16( nRed );
     329        4086 :     rOStream.WriteUInt16( nGreen );
     330        4086 :     rOStream.WriteUInt16( nBlue );
     331             : 
     332        4086 :     return rOStream;
     333             : }
     334             : 
     335             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11