1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 #ifndef _BGFX_COLOR_BCOLORMODIFIER_HXX 23 #define _BGFX_COLOR_BCOLORMODIFIER_HXX 24 25 #include <basegfx/color/bcolor.hxx> 26 #include <boost/utility.hpp> 27 #include <boost/shared_ptr.hpp> 28 #include <vector> 29 30 ////////////////////////////////////////////////////////////////////////////// 31 32 namespace basegfx 33 { 34 /** base class to define color modifications 35 36 The basic idea is to have instances of color modifiers where each 37 of these can be asked to get a modified version of a color. This 38 can be as easy as to return a fixed color, but may also do any 39 other computation based on the given source color and the local 40 algorythm to apply. 41 42 This base implementation defines the abstract base class. Every 43 derivation offers another color blending effect, when needed with 44 parameters for that blending defined as members. 45 46 As long as aw080 is not applied, an operator== is needed to implement 47 the operator== of the primitive based on this instances. 48 49 For the exact definitions of the color blending applied refer to the 50 implementation of the method getModifiedColor 51 52 BColorModifier is not copyable (no copy constructor, no assigment 53 operator); local values cannot be changed after construction. The 54 instances are cheap and the idea is to create them on demand. To 55 be able to reuse these as much as possible, a define for a 56 ::boost::shared_ptr named BColorModifierSharedPtr exists below. 57 All usages should handle instances of BColorModifier encapsulated 58 into these shared pointers. 59 */ 60 class BColorModifier : private boost::noncopyable 61 { 62 private: 63 protected: 64 // noone is allowed to incarnate the abstract base class 65 // except derivations BColorModifier()66 BColorModifier() {} 67 68 public: 69 // noone should directly destroy it; all incarnations should be 70 // handled in a boost::shared_ptr of type BColorModifierSharedPtr 71 virtual ~BColorModifier(); 72 73 // compare operator 74 virtual bool operator==(const BColorModifier& rCompare) const = 0; operator !=(const BColorModifier & rCompare) const75 bool operator!=(const BColorModifier& rCompare) const 76 { 77 return !(operator==(rCompare)); 78 } 79 80 // compute modified color 81 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const = 0; 82 }; 83 } // end of namespace basegfx 84 85 ////////////////////////////////////////////////////////////////////////////// 86 87 namespace basegfx 88 { 89 /** convert color to gray 90 91 returns a color where red green and blue are replaced with the 92 luminance value calculated based on the source color by using 93 the following weights: r * 0.30, g * 0.59, b * 0.11 94 */ 95 class BColorModifier_gray : public BColorModifier 96 { 97 private: 98 protected: 99 public: BColorModifier_gray()100 BColorModifier_gray() 101 : BColorModifier() 102 { 103 } 104 105 virtual ~BColorModifier_gray(); 106 107 // compare operator 108 virtual bool operator==(const BColorModifier& rCompare) const; 109 110 // compute modified color 111 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 112 }; 113 } // end of namespace basegfx 114 115 ////////////////////////////////////////////////////////////////////////////// 116 117 namespace basegfx 118 { 119 /** invert color 120 121 returns a color where red green and blue are inverted using 1.0 - n 122 */ 123 class BColorModifier_invert : public BColorModifier 124 { 125 private: 126 protected: 127 public: BColorModifier_invert()128 BColorModifier_invert() 129 : BColorModifier() 130 { 131 } 132 133 virtual ~BColorModifier_invert(); 134 135 // compare operator 136 virtual bool operator==(const BColorModifier& rCompare) const; 137 138 // compute modified color 139 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 140 }; 141 } // end of namespace basegfx 142 143 ////////////////////////////////////////////////////////////////////////////// 144 145 namespace basegfx 146 { 147 /** convert to alpha based on luminance 148 149 returns a color where red green and blue are first weighted and added 150 to build a luminance value which is then inverted and used for red, 151 green and blue. The weights are r * 0.2125 + g * 0.7154 + b * 0.0721. 152 This derivation is used for the svg importer and does exactly what SVG 153 defines for this needed case. 154 */ 155 class BColorModifier_luminance_to_alpha : public BColorModifier 156 { 157 private: 158 protected: 159 public: BColorModifier_luminance_to_alpha()160 BColorModifier_luminance_to_alpha() 161 : BColorModifier() 162 { 163 } 164 165 virtual ~BColorModifier_luminance_to_alpha(); 166 167 // compare operator 168 virtual bool operator==(const BColorModifier& rCompare) const; 169 170 // compute modified color 171 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 172 }; 173 } // end of namespace basegfx 174 175 ////////////////////////////////////////////////////////////////////////////// 176 177 namespace basegfx 178 { 179 /** replace color 180 181 does not use the source color at all, but always returns the 182 given color, replacing everything. Useful e.g. for unified shadow 183 creation 184 */ 185 class BColorModifier_replace : public BColorModifier 186 { 187 private: 188 ::basegfx::BColor maBColor; 189 190 protected: 191 public: BColorModifier_replace(const::basegfx::BColor & rBColor)192 BColorModifier_replace(const ::basegfx::BColor& rBColor) 193 : BColorModifier(), 194 maBColor(rBColor) 195 { 196 } 197 198 virtual ~BColorModifier_replace(); 199 200 // data access getBColor() const201 const ::basegfx::BColor& getBColor() const { return maBColor; } 202 203 // compare operator 204 virtual bool operator==(const BColorModifier& rCompare) const; 205 206 // compute modified color 207 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 208 }; 209 } // end of namespace basegfx 210 211 ////////////////////////////////////////////////////////////////////////////// 212 213 namespace basegfx 214 { 215 /** interpolate color 216 217 returns an interpolated color mixed by the given value (f) in the range 218 [0.0 .. 1.0] and the given color (col) as follows: 219 220 col * (1 - f) + aSourceColor * f 221 */ 222 class BColorModifier_interpolate : public BColorModifier 223 { 224 private: 225 ::basegfx::BColor maBColor; 226 double mfValue; 227 228 protected: 229 public: BColorModifier_interpolate(const::basegfx::BColor & rBColor,double fValue)230 BColorModifier_interpolate(const ::basegfx::BColor& rBColor, double fValue) 231 : BColorModifier(), 232 maBColor(rBColor), 233 mfValue(fValue) 234 { 235 } 236 237 virtual ~BColorModifier_interpolate(); 238 239 // data access getBColor() const240 const ::basegfx::BColor& getBColor() const { return maBColor; } getValue() const241 double getValue() const { return mfValue; } 242 243 // compare operator 244 virtual bool operator==(const BColorModifier& rCompare) const; 245 246 // compute modified color 247 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 248 }; 249 } // end of namespace basegfx 250 251 ////////////////////////////////////////////////////////////////////////////// 252 253 namespace basegfx 254 { 255 /** convert color to black and white 256 257 returns black when the luminance of the given color is less than 258 the given treshhold value in the range [0.0 .. 1.0], else white 259 */ 260 class BColorModifier_black_and_white : public BColorModifier 261 { 262 private: 263 double mfValue; 264 265 protected: 266 public: BColorModifier_black_and_white(double fValue)267 BColorModifier_black_and_white(double fValue) 268 : BColorModifier(), 269 mfValue(fValue) 270 { 271 } 272 273 virtual ~BColorModifier_black_and_white(); 274 275 // data access getValue() const276 double getValue() const { return mfValue; } 277 278 // compare operator 279 virtual bool operator==(const BColorModifier& rCompare) const; 280 281 // compute modified color 282 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 283 }; 284 } // end of namespace basegfx 285 286 ////////////////////////////////////////////////////////////////////////////// 287 288 namespace basegfx 289 { 290 /** gamma correction 291 292 Input is a gamma correction value in the range ]0.0 .. 10.0]; the 293 color values get correted using 294 295 col(r,g,b) = clamp(pow(col(r,g,b), 1.0 / gamma), 0.0, 1.0) 296 */ 297 class BColorModifier_gamma : public BColorModifier 298 { 299 private: 300 double mfValue; 301 double mfInvValue; 302 303 /// bitfield 304 bool mbUseIt : 1; 305 306 protected: 307 public: 308 BColorModifier_gamma(double fValue); 309 310 virtual ~BColorModifier_gamma(); 311 312 // data access getValue() const313 double getValue() const { return mfValue; } 314 315 // compare operator 316 virtual bool operator==(const BColorModifier& rCompare) const; 317 318 // compute modified color 319 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 320 }; 321 } // end of namespace basegfx 322 323 ////////////////////////////////////////////////////////////////////////////// 324 325 namespace basegfx 326 { 327 /** Red, Green, Blue, Luminance and Contrast correction 328 329 Input are percent values from [-1.0 .. 1-0] which correspond to -100% to 100% 330 correction of Red, Green, Blue, Luminance or Contrast. 0.0 means no change of 331 the corresponding channel. All these are combined (but can be used single) to 332 - be able to cover a bigger change range utilizing the cmobination 333 - allow execution by a small, common, precalculated table 334 */ 335 class BColorModifier_RGBLuminanceContrast : public BColorModifier 336 { 337 private: 338 double mfRed; 339 double mfGreen; 340 double mfBlue; 341 double mfLuminance; 342 double mfContrast; 343 344 double mfContrastOff; 345 double mfRedOff; 346 double mfGreenOff; 347 double mfBlueOff; 348 349 /// bitfield 350 bool mbUseIt : 1; 351 352 protected: 353 public: 354 BColorModifier_RGBLuminanceContrast(double fRed, double fGreen, double fBlue, double fLuminance, double fContrast); 355 356 virtual ~BColorModifier_RGBLuminanceContrast(); 357 358 // data access getRed() const359 double getRed() const { return mfRed; } getGreen() const360 double getGreen() const { return mfGreen; } getBlue() const361 double getBlue() const { return mfBlue; } getLuminance() const362 double getLuminance() const { return mfLuminance; } getContrast() const363 double getContrast() const { return mfContrast; } 364 365 // compare operator 366 virtual bool operator==(const BColorModifier& rCompare) const; 367 368 // compute modified color 369 virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const; 370 }; 371 } // end of namespace basegfx 372 373 ////////////////////////////////////////////////////////////////////////////// 374 375 namespace basegfx 376 { 377 /// typedef to allow working with shared instances of BColorModifier 378 /// for the whole mechanism 379 typedef ::boost::shared_ptr< BColorModifier > BColorModifierSharedPtr; 380 381 /** Class to hold a stack of BColorModifierSharedPtrs and to get the modified color with 382 applying all existing entry changes as defined in the stack. Instances of BColorModifier 383 can be pushed and popped to change the stack. 384 385 All references to BColorModifier members use shared pointers, thus instances of 386 BColorModifierStack can be copied by the default mechanisms if needed. 387 */ 388 class BColorModifierStack 389 { 390 protected: 391 ::std::vector< BColorModifierSharedPtr > maBColorModifiers; 392 393 public: count() const394 sal_uInt32 count() const 395 { 396 return maBColorModifiers.size(); 397 } 398 getBColorModifier(sal_uInt32 nIndex) const399 const BColorModifierSharedPtr& getBColorModifier(sal_uInt32 nIndex) const 400 { 401 OSL_ENSURE(nIndex < count(), "BColorModifierStack: Access out of range (!)"); 402 return maBColorModifiers[nIndex]; 403 } 404 405 // get the color in it's modified form by applying all existing BColorModifiers, 406 // from back to front (the newest first) 407 ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& rSource) const; 408 push(const BColorModifierSharedPtr & rNew)409 void push(const BColorModifierSharedPtr& rNew) 410 { 411 maBColorModifiers.push_back(rNew); 412 } 413 pop()414 void pop() 415 { 416 maBColorModifiers.pop_back(); 417 } 418 }; 419 } // end of namespace basegfx 420 421 ////////////////////////////////////////////////////////////////////////////// 422 423 #endif // _BGFX_COLOR_BCOLORMODIFIER_HXX 424 425 ////////////////////////////////////////////////////////////////////////////// 426 // eof 427