diff options
Diffstat (limited to 'include/basegfx/color')
-rw-r--r-- | include/basegfx/color/bcolor.hxx | 185 | ||||
-rw-r--r-- | include/basegfx/color/bcolormodifier.hxx | 336 | ||||
-rw-r--r-- | include/basegfx/color/bcolortools.hxx | 43 |
3 files changed, 564 insertions, 0 deletions
diff --git a/include/basegfx/color/bcolor.hxx b/include/basegfx/color/bcolor.hxx new file mode 100644 index 000000000..d8788b1cf --- /dev/null +++ b/include/basegfx/color/bcolor.hxx @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <sal/config.h> + +#include <algorithm> +#include <ostream> + +#include <basegfx/tuple/b3dtuple.hxx> +#include <basegfx/basegfxdllapi.h> + +namespace basegfx +{ + /** Base Color class with three double values + + This class derives all operators and common handling for + a 3D data class from B3DTuple. All necessary extensions + which are special for colors will be added here. + + @see B3DTuple + */ + class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColor : public B3DTuple + { + public: + /** Create a Color with red, green and blue components from [0.0 to 1.0] + + The color is initialized to (0.0, 0.0, 0.0) + */ + BColor() + {} + + /** Create a 3D Color + + @param fRed + @param fGreen + @param fBlue + These parameters are used to initialize the red, green and blue intensities of the color + */ + BColor(double fRed, double fGreen, double fBlue) + : B3DTuple(fRed, fGreen, fBlue) + {} + + /** Create a 3D Color + + @param fLuminosity + The parameter is used to initialize the red, green and blue intensities of the color + */ + explicit BColor(double fLuminosity) + : B3DTuple(fLuminosity, fLuminosity, fLuminosity) + {} + + /** constructor with tuple to allow copy-constructing + from B3DTuple-based classes + */ + BColor(const ::basegfx::B3DTuple& rTuple) + : B3DTuple(rTuple) + {} + + // data access read + double getRed() const { return mfX; } + double getGreen() const { return mfY; } + double getBlue() const { return mfZ; } + + // data access write + void setRed(double fNew) { mfX = fNew; } + void setGreen(double fNew) { mfY = fNew; } + void setBlue(double fNew) { mfZ = fNew; } + + /** *=operator to allow usage from BColor, too + */ + BColor& operator*=( const BColor& rPnt ) + { + mfX *= rPnt.mfX; + mfY *= rPnt.mfY; + mfZ *= rPnt.mfZ; + return *this; + } + + /** *=operator to allow usage from BColor, too + */ + BColor& operator*=(double t) + { + mfX *= t; + mfY *= t; + mfZ *= t; + return *this; + } + + /** assignment operator to allow assigning the results + of B3DTuple calculations + */ + BColor& operator=( const ::basegfx::B3DTuple& rVec ) + { + mfX = rVec.getX(); + mfY = rVec.getY(); + mfZ = rVec.getZ(); + return *this; + } + + // luminance + double luminance() const + { + const double fRedWeight(77.0 / 256.0); // 0.30 + const double fGreenWeight(151.0 / 256.0); // 0.59 + const double fBlueWeight(28.0 / 256.0); // 0.11 + + return (mfX * fRedWeight + mfY * fGreenWeight + mfZ * fBlueWeight); + } + + // distances in color space + double getDistanceRed(const BColor& rColor) const { return (getRed() > rColor.getRed() ? getRed() - rColor.getRed() : rColor.getRed() - getRed()); } + double getDistanceGreen(const BColor& rColor) const { return (getGreen() > rColor.getGreen() ? getGreen() - rColor.getGreen() : rColor.getGreen() - getGreen()); } + double getDistanceBlue(const BColor& rColor) const { return (getBlue() > rColor.getBlue() ? getBlue() - rColor.getBlue() : rColor.getBlue() - getBlue()); } + + double getDistance(const BColor& rColor) const + { + const double fDistR(getDistanceRed(rColor)); + const double fDistG(getDistanceGreen(rColor)); + const double fDistB(getDistanceBlue(rColor)); + + return sqrt(fDistR * fDistR + fDistG * fDistG + fDistB * fDistB); + } + + double getMaximumDistance(const BColor& rColor) const + { + const double fDistR(getDistanceRed(rColor)); + const double fDistG(getDistanceGreen(rColor)); + const double fDistB(getDistanceBlue(rColor)); + + double fRetval(std::max(fDistR, fDistG)); + return std::max(fRetval, fDistB); + } + + // clamp color to [0.0..1.0] values in all three intensity components + BColor& clamp() + { + mfX = std::clamp(mfX, 0.0, 1.0); + mfY = std::clamp(mfY, 0.0, 1.0); + mfZ = std::clamp(mfZ, 0.0, 1.0); + return *this; + } + + void invert() + { + mfX = 1.0 - mfX; + mfY = 1.0 - mfY; + mfZ = 1.0 - mfZ; + } + + static const BColor& getEmptyBColor() + { + return static_cast<const BColor&>( ::basegfx::B3DTuple::getEmptyTuple() ); + } + + }; + + template<typename charT, typename traits> + std::basic_ostream<charT, traits> & operator <<( + std::basic_ostream<charT, traits> & stream, BColor const & color) + { + return stream + << '[' << color.getRed() << ", " << color.getGreen() << ", " + << color.getBlue() << ']'; + } +} // end of namespace basegfx + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/basegfx/color/bcolormodifier.hxx b/include/basegfx/color/bcolormodifier.hxx new file mode 100644 index 000000000..b39849ed7 --- /dev/null +++ b/include/basegfx/color/bcolormodifier.hxx @@ -0,0 +1,336 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <config_options.h> +#include <basegfx/basegfxdllapi.h> +#include <basegfx/color/bcolor.hxx> + +#include <osl/diagnose.h> + +#include <memory> +#include <vector> + +namespace basegfx +{ + /** base class to define color modifications + + The basic idea is to have instances of color modifiers where each + of these can be asked to get a modified version of a color. This + can be as easy as to return a fixed color, but may also do any + other computation based on the given source color and the local + algorithm to apply. + + This base implementation defines the abstract base class. Every + derivation offers another color blending effect, when needed with + parameters for that blending defined as members. + + As long as aw080 is not applied, an operator== is needed to implement + the operator== of the primitive based on this instances. + + For the exact definitions of the color blending applied refer to the + implementation of the method getModifiedColor + + BColorModifier is not copyable (no copy constructor, no assignment + operator); local values cannot be changed after construction. The + instances are cheap and the idea is to create them on demand. To + be able to reuse these as much as possible, a define for a + std::shared_ptr named BColorModifierSharedPtr exists below. + All usages should handle instances of BColorModifier encapsulated + into these shared pointers. + */ + class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier + { + private: + BColorModifier(const BColorModifier&) = delete; + BColorModifier& operator=(const BColorModifier&) = delete; + protected: + // no one is allowed to incarnate the abstract base class + // except derivations + BColorModifier() {} + + public: + // no one should directly destroy it; all incarnations should be + // handled in a std::shared_ptr of type BColorModifierSharedPtr + virtual ~BColorModifier(); + + // compare operator + virtual bool operator==(const BColorModifier& rCompare) const = 0; + bool operator!=(const BColorModifier& rCompare) const + { + return !(operator==(rCompare)); + } + + // compute modified color + virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const = 0; + }; + + /** convert color to gray + */ + class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_gray final : public BColorModifier + { + public: + BColorModifier_gray() + { + } + + virtual ~BColorModifier_gray() override; + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /** invert color + + returns a color where red green and blue are inverted using 1.0 - n + */ + class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_invert final : public BColorModifier + { + public: + BColorModifier_invert() + { + } + + virtual ~BColorModifier_invert() override; + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /** convert to alpha based on luminance + + returns a color where red green and blue are first weighted and added + to build a luminance value which is then inverted and used for red, + green and blue. The weights are r * 0.2125 + g * 0.7154 + b * 0.0721. + This derivation is used for the svg importer and does exactly what SVG + defines for this needed case. + */ + class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_luminance_to_alpha final : public BColorModifier + { + public: + BColorModifier_luminance_to_alpha() + { + } + + virtual ~BColorModifier_luminance_to_alpha() override; + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /** replace color + + does not use the source color at all, but always returns the + given color, replacing everything. Useful e.g. for unified shadow + creation + */ + class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_replace final : public BColorModifier + { + private: + ::basegfx::BColor maBColor; + + public: + BColorModifier_replace(const ::basegfx::BColor& rBColor) + : maBColor(rBColor) + { + } + + virtual ~BColorModifier_replace() override; + + // data access + const ::basegfx::BColor& getBColor() const { return maBColor; } + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /** interpolate color + + returns an interpolated color mixed by the given value (f) in the range + [0.0 .. 1.0] and the given color (col) as follows: + + col * (1 - f) + aSourceColor * f + */ + class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC BColorModifier_interpolate final : public BColorModifier + { + private: + ::basegfx::BColor maBColor; + double mfValue; + + public: + BColorModifier_interpolate(const ::basegfx::BColor& rBColor, double fValue) + : maBColor(rBColor), + mfValue(fValue) + { + } + + virtual ~BColorModifier_interpolate() override; + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /** convert color to black and white + + returns black when the luminance of the given color is less than + the given threshold value in the range [0.0 .. 1.0], else white + */ + class SAL_WARN_UNUSED UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) BColorModifier_black_and_white final : public BColorModifier + { + private: + double mfValue; + + public: + BColorModifier_black_and_white(double fValue) + : mfValue(fValue) + { + } + + virtual ~BColorModifier_black_and_white() override; + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /** gamma correction + + Input is a gamma correction value in the range ]0.0 .. 10.0]; the + color values get corrected using + + col(r,g,b) = clamp(pow(col(r,g,b), 1.0 / gamma), 0.0, 1.0) + */ + class SAL_WARN_UNUSED UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) BColorModifier_gamma final : public BColorModifier + { + private: + double mfValue; + double mfInvValue; + + bool mbUseIt : 1; + + public: + BColorModifier_gamma(double fValue); + + virtual ~BColorModifier_gamma() override; + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /** Red, Green, Blue, Luminance and Contrast correction + + Input are percent values from [-1.0 .. 1-0] which correspond to -100% to 100% + correction of Red, Green, Blue, Luminance or Contrast. 0.0 means no change of + the corresponding channel. All these are combined (but can be used single) to + - be able to cover a bigger change range utilizing the combination + - allow execution by a small, common, precalculated table + */ + class SAL_WARN_UNUSED UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) BColorModifier_RGBLuminanceContrast final : public BColorModifier + { + private: + double mfRed; + double mfGreen; + double mfBlue; + double mfLuminance; + double mfContrast; + + double mfContrastOff; + double mfRedOff; + double mfGreenOff; + double mfBlueOff; + + bool mbUseIt : 1; + + public: + BColorModifier_RGBLuminanceContrast(double fRed, double fGreen, double fBlue, double fLuminance, double fContrast); + + virtual ~BColorModifier_RGBLuminanceContrast() override; + + // compare operator + SAL_DLLPRIVATE virtual bool operator==(const BColorModifier& rCompare) const override; + + // compute modified color + SAL_DLLPRIVATE virtual ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& aSourceColor) const override; + }; + + /// typedef to allow working with shared instances of BColorModifier + /// for the whole mechanism + typedef std::shared_ptr< BColorModifier > BColorModifierSharedPtr; + + /** Class to hold a stack of BColorModifierSharedPtrs and to get the modified color with + applying all existing entry changes as defined in the stack. Instances of BColorModifier + can be pushed and popped to change the stack. + + All references to BColorModifier members use shared pointers, thus instances of + BColorModifierStack can be copied by the default mechanisms if needed. + */ + class BASEGFX_DLLPUBLIC BColorModifierStack final + { + ::std::vector< BColorModifierSharedPtr > maBColorModifiers; + + public: + sal_uInt32 count() const + { + return maBColorModifiers.size(); + } + + const BColorModifierSharedPtr& getBColorModifier(sal_uInt32 nIndex) const + { + OSL_ENSURE(nIndex < count(), "BColorModifierStack: Access out of range (!)"); + return maBColorModifiers[nIndex]; + } + + // get the color in its modified form by applying all existing BColorModifiers, + // from back to front (the newest first) + ::basegfx::BColor getModifiedColor(const ::basegfx::BColor& rSource) const; + + void push(const BColorModifierSharedPtr& rNew) + { + maBColorModifiers.push_back(rNew); + } + + void pop() + { + maBColorModifiers.pop_back(); + } + }; +} // end of namespace basegfx + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/basegfx/color/bcolortools.hxx b/include/basegfx/color/bcolortools.hxx new file mode 100644 index 000000000..8af2b7c94 --- /dev/null +++ b/include/basegfx/color/bcolortools.hxx @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include <basegfx/basegfxdllapi.h> + +namespace basegfx +{ +class BColor; +} + +namespace basegfx::utils +{ +/// Transform from RGB to HSL +BASEGFX_DLLPUBLIC BColor rgb2hsl(const BColor& rRGBColor); +/// Transform from HSL to RGB +BASEGFX_DLLPUBLIC BColor hsl2rgb(const BColor& rHSLColor); + +/// Transform from RGB to HSV +BASEGFX_DLLPUBLIC BColor rgb2hsv(const BColor& rRGBColor); +/// Transform from HSV to RGB +BASEGFX_DLLPUBLIC BColor hsv2rgb(const BColor& rHSVColor); + +} // end of namespace basegfx + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |