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