summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2019-04-20 11:06:11 +0900
committerTomaž Vajngerl <quikee@gmail.com>2019-04-21 14:20:19 +0200
commitd487d6e082bc7ce652217578ffd37397a59cc3ca (patch)
treec6498c4b2f4cb042013547d32a8ad98a30c238d5 /include
parentd077b19a3f617f5ef3d65fc20a136a9107c47199 (diff)
rework Color to have R,G,B,A public variables
Color is a wrapper around a sal_uInt32 variable. With a union, separate channels R, G, B, A sal_uInt8 variables can be added that occupy the same memory. This makes it much easier to access each color component separately, which is used quite a lot by various algorithms. This also adds the variables to public so everyone can enjoy the benefits. Tests have been extended to make sure this doesn't break the existing algroithms. Change-Id: I2e78e12df68e8c7f0f49420eef5e659b335ee397 Reviewed-on: https://gerrit.libreoffice.org/71002 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'include')
-rw-r--r--include/tools/color.hxx85
1 files changed, 47 insertions, 38 deletions
diff --git a/include/tools/color.hxx b/include/tools/color.hxx
index 26d587b7e1f5..25032c5d29b9 100644
--- a/include/tools/color.hxx
+++ b/include/tools/color.hxx
@@ -26,29 +26,44 @@
class SvStream;
-constexpr sal_uInt8 COLORDATA_RED( sal_uInt32 n ) { return static_cast<sal_uInt8>(n>>16); }
-constexpr sal_uInt8 COLORDATA_GREEN( sal_uInt32 n ) { return static_cast<sal_uInt8>(static_cast<sal_uInt16>(n) >> 8); }
-constexpr sal_uInt8 COLORDATA_BLUE( sal_uInt32 n ) { return static_cast<sal_uInt8>(n); }
-constexpr sal_uInt8 COLORDATA_TRANSPARENCY( sal_uInt32 n ) { return static_cast<sal_uInt8>(n>>24); }
constexpr sal_uInt32 COLORDATA_RGB( sal_uInt32 n ) { return static_cast<sal_uInt32>(n & 0x00FFFFFF); }
// Color
class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Color final
{
- sal_uInt32 mnColor;
-
public:
+ union
+ {
+ sal_uInt32 mValue;
+ struct
+ {
+ #ifdef OSL_BIGENDIAN
+ sal_uInt8 A;
+ sal_uInt8 R;
+ sal_uInt8 G;
+ sal_uInt8 B;
+ #else
+ sal_uInt8 B;
+ sal_uInt8 G;
+ sal_uInt8 R;
+ sal_uInt8 A;
+ #endif
+ };
+ };
+
constexpr Color()
- : mnColor(0) // black
+ : mValue(0) // black
{}
+
constexpr Color(sal_uInt32 nColor)
- : mnColor(nColor)
+ : mValue(nColor)
{}
+
constexpr Color(sal_uInt8 nTransparency, sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
- : mnColor( sal_uInt32(nBlue) | (sal_uInt32(nGreen) << 8) | (sal_uInt32(nRed) << 16)
- | (sal_uInt32(nTransparency) << 24) )
+ : mValue(sal_uInt32(nBlue) | (sal_uInt32(nGreen) << 8) | (sal_uInt32(nRed) << 16) | (sal_uInt32(nTransparency) << 24))
{}
+
constexpr Color(sal_uInt8 nRed, sal_uInt8 nGreen, sal_uInt8 nBlue)
: Color(0, nRed, nGreen, nBlue)
{}
@@ -56,51 +71,51 @@ public:
// constructor to create a tools-Color from ::basegfx::BColor
explicit Color(const basegfx::BColor& rBColor)
: Color(0,
- sal_uInt8((rBColor.getRed() * 255.0) + 0.5),
- sal_uInt8((rBColor.getGreen() * 255.0) + 0.5),
- sal_uInt8((rBColor.getBlue() * 255.0) + 0.5))
+ sal_uInt8(std::lround(rBColor.getRed() * 255.0)),
+ sal_uInt8(std::lround(rBColor.getGreen() * 255.0)),
+ sal_uInt8(std::lround(rBColor.getBlue() * 255.0)))
{}
/** Primarily used when passing Color objects to UNO API */
constexpr explicit operator sal_uInt32() const
{
- return mnColor;
+ return mValue;
}
constexpr explicit operator sal_Int32() const
{
- return sal_Int32(mnColor);
+ return sal_Int32(mValue);
}
- bool operator<(const Color& b) const
+ bool operator<(const Color& aCompareColor) const
{
- return mnColor < b.mnColor;
+ return mValue < aCompareColor.mValue;
}
void SetRed(sal_uInt8 nRed);
sal_uInt8 GetRed() const
{
- return COLORDATA_RED(mnColor);
+ return R;
}
void SetGreen(sal_uInt8 nGreen);
sal_uInt8 GetGreen() const
{
- return COLORDATA_GREEN(mnColor);
+ return G;
}
void SetBlue(sal_uInt8 nBlue);
sal_uInt8 GetBlue() const
{
- return COLORDATA_BLUE(mnColor);
+ return B;
}
void SetTransparency(sal_uInt8 nTransparency);
sal_uInt8 GetTransparency() const
{
- return COLORDATA_TRANSPARENCY(mnColor);
+ return A;
}
Color GetRGBColor() const
{
- return COLORDATA_RGB(mnColor);
+ return COLORDATA_RGB(mValue);
}
sal_uInt8 GetColorError(const Color& rCompareColor) const;
@@ -141,7 +156,7 @@ public:
bool operator==(const Color& rColor) const
{
- return mnColor == rColor.mnColor;
+ return mValue == rColor.mValue;
}
bool operator!=(const Color& rColor) const
{
@@ -167,38 +182,32 @@ public:
inline void Color::SetRed( sal_uInt8 nRed )
{
- mnColor &= 0xFF00FFFF;
- mnColor |= static_cast<sal_uInt32>(nRed)<<16;
+ R = nRed;
}
inline void Color::SetGreen( sal_uInt8 nGreen )
{
- mnColor &= 0xFFFF00FF;
- mnColor |= static_cast<sal_uInt16>(nGreen)<<8;
+ G = nGreen;
}
inline void Color::SetBlue( sal_uInt8 nBlue )
{
- mnColor &= 0xFFFFFF00;
- mnColor |= nBlue;
+ B = nBlue;
}
inline void Color::SetTransparency( sal_uInt8 nTransparency )
{
- mnColor &= 0x00FFFFFF;
- mnColor |= static_cast<sal_uInt32>(nTransparency)<<24;
+ A = nTransparency;
}
inline bool Color::IsRGBEqual( const Color& rColor ) const
{
- return COLORDATA_RGB( mnColor ) == COLORDATA_RGB(rColor.mnColor);
+ return COLORDATA_RGB(mValue) == COLORDATA_RGB(rColor.mValue);
}
inline sal_uInt8 Color::GetLuminance() const
{
- return static_cast<sal_uInt8>((COLORDATA_BLUE(mnColor) * 29UL +
- COLORDATA_GREEN(mnColor) * 151UL +
- COLORDATA_RED(mnColor) * 76UL) >> 8);
+ return sal_uInt8((B * 29UL + G * 151UL + R * 76UL) >> 8);
}
constexpr sal_uInt8 ColorChannelMerge(sal_uInt8 nDst, sal_uInt8 nSrc, sal_uInt8 nSrcTrans)
@@ -208,9 +217,9 @@ constexpr sal_uInt8 ColorChannelMerge(sal_uInt8 nDst, sal_uInt8 nSrc, sal_uInt8
inline void Color::Merge( const Color& rMergeColor, sal_uInt8 cTransparency )
{
- SetRed(ColorChannelMerge(COLORDATA_RED(mnColor), COLORDATA_RED(rMergeColor.mnColor), cTransparency));
- SetGreen(ColorChannelMerge(COLORDATA_GREEN(mnColor), COLORDATA_GREEN(rMergeColor.mnColor), cTransparency));
- SetBlue(ColorChannelMerge(COLORDATA_BLUE(mnColor), COLORDATA_BLUE(rMergeColor.mnColor), cTransparency));
+ R = ColorChannelMerge(R, rMergeColor.R, cTransparency);
+ G = ColorChannelMerge(G, rMergeColor.G, cTransparency);
+ B = ColorChannelMerge(B, rMergeColor.B, cTransparency);
}
// to reduce the noise when moving these into and out of Any