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 #ifndef INCLUDED_TOOLS_COLOR_HXX 20 #define INCLUDED_TOOLS_COLOR_HXX 21 22 #include <sal/types.h> 23 #include <tools/toolsdllapi.h> 24 #include <com/sun/star/uno/Any.hxx> 25 #include <basegfx/color/bcolor.hxx> 26 27 namespace color 28 { 29 30 constexpr sal_uInt32 extractRGB(sal_uInt32 nColorNumber) 31 { 32 return nColorNumber & 0x00FFFFFF; 33 } 34 35 } 36 37 // Color 38 39 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Color 40 { 41 // data intentionally public; read the commit log! 42 public: 43 union 44 { 45 sal_uInt32 mValue; 46 struct 47 { 48 #ifdef OSL_BIGENDIAN 49 sal_uInt8 A; 50 sal_uInt8 R; 51 sal_uInt8 G; 52 sal_uInt8 B; 53 #else 54 sal_uInt8 B; 55 sal_uInt8 G; 56 sal_uInt8 R; 57 sal_uInt8 A; 58 #endif 59 }; 60 }; 61 62 public: 63 constexpr Color() 64 : mValue(0) // black 65 {} 66 67 constexpr Color(sal_uInt32 nColor) 68 : mValue(nColor) 69 {} 70 71 constexpr Color(sal_uInt8 nTransparency, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue) 72 : mValue(sal_uInt32(nBlue) | (sal_uInt32(nGreen) << 8) | (sal_uInt32(nRed) << 16) | (sal_uInt32(nTransparency) << 24)) 73 {} 74 75 constexpr Color(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue) 76 : Color(0, nRed, nGreen, nBlue) 77 {} 78 79 // constructor to create a tools-Color from ::basegfx::BColor 80 explicit Color(const basegfx::BColor& rBColor) 81 : Color(0, 82 sal_uInt8(std::lround(rBColor.getRed() * 255.0)), 83 sal_uInt8(std::lround(rBColor.getGreen() * 255.0)), 84 sal_uInt8(std::lround(rBColor.getBlue() * 255.0))) 85 {} 86 87 /** Primarily used when passing Color objects to UNO API */ 88 constexpr explicit operator sal_uInt32() const 89 { 90 return mValue; 91 } 92 93 constexpr explicit operator sal_Int32() const 94 { 95 return sal_Int32(mValue); 96 } 97 98 bool operator<(const Color& aCompareColor) const 99 { 100 return mValue < aCompareColor.mValue; 101 } 102 103 void SetRed(sal_uInt8 nRed); 104 sal_uInt8 GetRed() const 105 { 106 return R; 107 } 108 void SetGreen(sal_uInt8 nGreen); 109 sal_uInt8 GetGreen() const 110 { 111 return G; 112 } 113 void SetBlue(sal_uInt8 nBlue); 114 sal_uInt8 GetBlue() const 115 { 116 return B; 117 } 118 void SetTransparency(sal_uInt8 nTransparency); 119 sal_uInt8 GetTransparency() const 120 { 121 return A; 122 } 123 124 Color GetRGBColor() const 125 { 126 return color::extractRGB(mValue); 127 } 128 129 sal_uInt16 GetColorError(const Color& rCompareColor) const; 130 131 sal_uInt8 GetLuminance() const; 132 void IncreaseLuminance(sal_uInt8 cLumInc); 133 void DecreaseLuminance(sal_uInt8 cLumDec); 134 135 void DecreaseContrast(sal_uInt8 cContDec); 136 137 /** 138 * Apply tint or shade to a color. 139 * 140 * The input value is the percentage (in 100th of percent) of how much the 141 * color changes towards the black (shade) or white (tint). If the value 142 * is positive, the color is tinted, if the value is negative, the color is 143 * shaded. 144 **/ 145 void ApplyTintOrShade(sal_Int16 n100thPercent); 146 147 void Invert(); 148 149 void Merge(const Color& rMergeColor, sal_uInt8 cTransparency); 150 151 bool IsRGBEqual(const Color& rColor) const; 152 153 // comparison with luminance thresholds 154 bool IsDark() const; 155 bool IsBright() const; 156 157 // color space conversion tools 158 // the range for h/s/b is: 159 // Hue: 0-360 degree 160 // Saturation: 0-100% 161 // Brightness: 0-100% 162 static Color HSBtoRGB(sal_uInt16 nHue, sal_uInt16 nSaturation, sal_uInt16 nBrightness); 163 void RGBtoHSB(sal_uInt16& nHue, sal_uInt16& nSaturation, sal_uInt16& nBrightness) const; 164 165 bool operator==(const Color& rColor) const 166 { 167 return mValue == rColor.mValue; 168 } 169 bool operator!=(const Color& rColor) const 170 { 171 return !(Color::operator==(rColor)); 172 } 173 174 // Return color as RGB hex string 175 // for example "00ff00" for green color 176 OUString AsRGBHexString() const; 177 178 // get ::basegfx::BColor from this color 179 basegfx::BColor getBColor() const 180 { 181 return basegfx::BColor(GetRed() / 255.0, GetGreen() / 255.0, GetBlue() / 255.0); 182 } 183 }; 184 185 inline void Color::SetRed( sal_uInt8 nRed ) 186 { 187 R = nRed; 188 } 189 190 inline void Color::SetGreen( sal_uInt8 nGreen ) 191 { 192 G = nGreen; 193 } 194 195 inline void Color::SetBlue( sal_uInt8 nBlue ) 196 { 197 B = nBlue; 198 } 199 200 inline void Color::SetTransparency( sal_uInt8 nTransparency ) 201 { 202 A = nTransparency; 203 } 204 205 inline bool Color::IsRGBEqual( const Color& rColor ) const 206 { 207 return color::extractRGB(mValue) == color::extractRGB(rColor.mValue); 208 } 209 210 inline sal_uInt8 Color::GetLuminance() const 211 { 212 return sal_uInt8((B * 29UL + G * 151UL + R * 76UL) >> 8); 213 } 214 215 constexpr sal_uInt8 ColorChannelMerge(sal_uInt8 nDst, sal_uInt8 nSrc, sal_uInt8 nSrcTrans) 216 { 217 return sal_uInt8(((sal_Int32(nDst) - nSrc) * nSrcTrans + ((nSrc << 8) | nDst)) >> 8); 218 } 219 220 inline void Color::Invert() 221 { 222 R = ~R; 223 G = ~G; 224 B = ~B; 225 } 226 227 inline sal_uInt16 Color::GetColorError( const Color& rColor ) const 228 { 229 return static_cast<sal_uInt16>( 230 abs(static_cast<int>(GetBlue()) - rColor.GetBlue()) + 231 abs(static_cast<int>(GetGreen()) - rColor.GetGreen()) + 232 abs(static_cast<int>(GetRed()) - rColor.GetRed())); 233 } 234 235 inline void Color::Merge( const Color& rMergeColor, sal_uInt8 cTransparency ) 236 { 237 R = ColorChannelMerge(R, rMergeColor.R, cTransparency); 238 G = ColorChannelMerge(G, rMergeColor.G, cTransparency); 239 B = ColorChannelMerge(B, rMergeColor.B, cTransparency); 240 } 241 242 // to reduce the noise when moving these into and out of Any 243 inline bool operator >>=( const css::uno::Any & rAny, Color & value ) 244 { 245 sal_Int32 nTmp; 246 if (!(rAny >>= nTmp)) 247 return false; 248 value = Color(nTmp); 249 return true; 250 } 251 252 inline void operator <<=( css::uno::Any & rAny, Color value ) 253 { 254 rAny <<= sal_Int32(value); 255 } 256 namespace com { namespace sun { namespace star { namespace uno { 257 template<> 258 inline Any makeAny( Color const & value ) 259 { 260 return Any(sal_Int32(value)); 261 } 262 } } } } 263 264 // Test compile time conversion of Color to sal_uInt32 265 266 static_assert (sal_uInt32(Color(0x00, 0x12, 0x34, 0x56)) == 0x00123456); 267 static_assert (sal_uInt32(Color(0x12, 0x34, 0x56)) == 0x00123456); 268 269 // Color types 270 271 constexpr ::Color COL_BLACK ( 0x00, 0x00, 0x00 ); 272 constexpr ::Color COL_BLUE ( 0x00, 0x00, 0x80 ); 273 constexpr ::Color COL_GREEN ( 0x00, 0x80, 0x00 ); 274 constexpr ::Color COL_CYAN ( 0x00, 0x80, 0x80 ); 275 constexpr ::Color COL_RED ( 0x80, 0x00, 0x00 ); 276 constexpr ::Color COL_MAGENTA ( 0x80, 0x00, 0x80 ); 277 constexpr ::Color COL_BROWN ( 0x80, 0x80, 0x00 ); 278 constexpr ::Color COL_GRAY ( 0x80, 0x80, 0x80 ); 279 constexpr ::Color COL_GRAY3 ( 0xCC, 0xCC, 0xCC ); 280 constexpr ::Color COL_GRAY7 ( 0x66, 0x66, 0x66 ); 281 constexpr ::Color COL_LIGHTGRAY ( 0xC0, 0xC0, 0xC0 ); 282 constexpr ::Color COL_LIGHTBLUE ( 0x00, 0x00, 0xFF ); 283 constexpr ::Color COL_LIGHTGREEN ( 0x00, 0xFF, 0x00 ); 284 constexpr ::Color COL_LIGHTCYAN ( 0x00, 0xFF, 0xFF ); 285 constexpr ::Color COL_LIGHTRED ( 0xFF, 0x00, 0x00 ); 286 constexpr ::Color COL_LIGHTMAGENTA ( 0xFF, 0x00, 0xFF ); 287 constexpr ::Color COL_LIGHTGRAYBLUE ( 0xE0, 0xE0, 0xFF ); 288 constexpr ::Color COL_YELLOW ( 0xFF, 0xFF, 0x00 ); 289 constexpr ::Color COL_WHITE ( 0xFF, 0xFF, 0xFF ); 290 constexpr ::Color COL_TRANSPARENT ( 0xFF, 0xFF, 0xFF, 0xFF ); 291 constexpr ::Color COL_AUTO ( 0xFF, 0xFF, 0xFF, 0xFF ); 292 constexpr ::Color COL_AUTHOR1_DARK ( 198, 146, 0 ); 293 constexpr ::Color COL_AUTHOR1_NORMAL ( 255, 255, 158 ); 294 constexpr ::Color COL_AUTHOR1_LIGHT ( 255, 255, 195 ); 295 constexpr ::Color COL_AUTHOR2_DARK ( 6, 70, 162 ); 296 constexpr ::Color COL_AUTHOR2_NORMAL ( 216, 232, 255 ); 297 constexpr ::Color COL_AUTHOR2_LIGHT ( 233, 242, 255 ); 298 constexpr ::Color COL_AUTHOR3_DARK ( 87, 157, 28 ); 299 constexpr ::Color COL_AUTHOR3_NORMAL ( 218, 248, 193 ); 300 constexpr ::Color COL_AUTHOR3_LIGHT ( 226, 250, 207 ); 301 constexpr ::Color COL_AUTHOR4_DARK ( 105, 43, 157 ); 302 constexpr ::Color COL_AUTHOR4_NORMAL ( 228, 210, 245 ); 303 constexpr ::Color COL_AUTHOR4_LIGHT ( 239, 228, 248 ); 304 constexpr ::Color COL_AUTHOR5_DARK ( 197, 0, 11 ); 305 constexpr ::Color COL_AUTHOR5_NORMAL ( 254, 205, 208 ); 306 constexpr ::Color COL_AUTHOR5_LIGHT ( 255, 227, 229 ); 307 constexpr ::Color COL_AUTHOR6_DARK ( 0, 128, 128 ); 308 constexpr ::Color COL_AUTHOR6_NORMAL ( 210, 246, 246 ); 309 constexpr ::Color COL_AUTHOR6_LIGHT ( 230, 250, 250 ); 310 constexpr ::Color COL_AUTHOR7_DARK ( 140, 132, 0 ); 311 constexpr ::Color COL_AUTHOR7_NORMAL ( 237, 252, 163 ); 312 constexpr ::Color COL_AUTHOR7_LIGHT ( 242, 254, 181 ); 313 constexpr ::Color COL_AUTHOR8_DARK ( 53, 85, 107 ); 314 constexpr ::Color COL_AUTHOR8_NORMAL ( 211, 222, 232 ); 315 constexpr ::Color COL_AUTHOR8_LIGHT ( 226, 234, 241 ); 316 constexpr ::Color COL_AUTHOR9_DARK ( 209, 118, 0 ); 317 constexpr ::Color COL_AUTHOR9_NORMAL ( 255, 226, 185 ); 318 constexpr ::Color COL_AUTHOR9_LIGHT ( 255, 231, 199 ); 319 320 template<typename charT, typename traits> 321 inline std::basic_ostream<charT, traits>& operator <<(std::basic_ostream<charT, traits>& rStream, const Color& rColor) 322 { 323 return rStream << "c[" << std::hex << std::setfill ('0') 324 << std::setw(2) << static_cast<int>(rColor.GetRed()) 325 << std::setw(2) << static_cast<int>(rColor.GetGreen()) 326 << std::setw(2) << static_cast<int>(rColor.GetBlue()) 327 << std::setw(2) << static_cast<int>(rColor.GetTransparency()) << "]"; 328 } 329 330 #endif 331 332 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 333
