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