summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2015-05-27 12:20:49 +0900
committerTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2015-08-27 08:30:49 +0900
commita0ab7c31a254285856f6520d069570647c56af22 (patch)
tree94e9145f5a36c0341cd7cf71975a420d4f0736b5
parentbba73f9e0f286f48fe02f7e232c53de79fc5f12c (diff)
Again add ability to change tint/shade of a color + unit test
Change-Id: I4c06290f09e5bfecd2c1de896e19cb5036a3a0e9
-rw-r--r--include/tools/color.hxx10
-rw-r--r--tools/qa/cppunit/test_color.cxx60
-rw-r--r--tools/source/generic/color.cxx26
3 files changed, 96 insertions, 0 deletions
diff --git a/include/tools/color.hxx b/include/tools/color.hxx
index f940dbcf5688..00c89e2e5e89 100644
--- a/include/tools/color.hxx
+++ b/include/tools/color.hxx
@@ -163,6 +163,16 @@ public:
void DecreaseContrast(sal_uInt8 cContDec);
+ /**
+ * Apply tint or shade to a color.
+ *
+ * The input value is the percentage (in 100th of percent) of how much the
+ * color changes towards the black (shade) or white (tint). If the value
+ * is positive, the color is tinted, if the value is negative, the color is
+ * shaded.
+ **/
+ void ApplyTintOrShade(sal_Int16 n100thPercent);
+
void Invert();
void Merge(const Color& rMergeColor, sal_uInt8 cTransparency);
diff --git a/tools/qa/cppunit/test_color.cxx b/tools/qa/cppunit/test_color.cxx
index 99f311fc5a4c..aeab12a1adb1 100644
--- a/tools/qa/cppunit/test_color.cxx
+++ b/tools/qa/cppunit/test_color.cxx
@@ -23,10 +23,12 @@ class Test: public CppUnit::TestFixture
public:
void test_asRGBColor();
void test_readAndWriteStream();
+ void test_ApplyTintOrShade();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(test_asRGBColor);
CPPUNIT_TEST(test_readAndWriteStream);
+ CPPUNIT_TEST(test_ApplyTintOrShade);
CPPUNIT_TEST_SUITE_END();
};
@@ -76,6 +78,64 @@ void Test::test_readAndWriteStream()
}
}
+bool checkTintShade(sal_uInt8 nR, sal_uInt8 nG, sal_uInt8 nB, OUString sReference, sal_Int16 nTintShade, OUString sExpected)
+{
+ Color aColor(nR, nG, nB);
+ if (sReference != aColor.AsRGBHexString())
+ return false;
+ aColor.ApplyTintOrShade(nTintShade);
+ return sExpected == aColor.AsRGBHexString();
+}
+
+void Test::test_ApplyTintOrShade()
+{
+ // BLACK reference
+
+ // 5% tint
+ CPPUNIT_ASSERT(checkTintShade(0x00, 0x00, 0x00, "000000", 500, "0d0d0d"));
+ // 15% tint
+ CPPUNIT_ASSERT(checkTintShade(0x00, 0x00, 0x00, "000000", 1500, "262626"));
+ // 25% tint
+ CPPUNIT_ASSERT(checkTintShade(0x00, 0x00, 0x00, "000000", 2500, "404040"));
+ // 50% tint
+ CPPUNIT_ASSERT(checkTintShade(0x00, 0x00, 0x00, "000000", 5000, "808080"));
+ // 100% tint
+ CPPUNIT_ASSERT(checkTintShade(0x00, 0x00, 0x00, "000000", 10000, "ffffff"));
+
+ // WHITE reference
+
+ // 5% shade
+ CPPUNIT_ASSERT(checkTintShade(0xff, 0xff, 0xff, "ffffff", -500, "f2f2f2"));
+ // 15% shade
+ CPPUNIT_ASSERT(checkTintShade(0xff, 0xff, 0xff, "ffffff", -1500, "d9d9d9"));
+ // 25% shade
+ CPPUNIT_ASSERT(checkTintShade(0xff, 0xff, 0xff, "ffffff", -2500, "bfbfbf"));
+ // 50% shade
+ CPPUNIT_ASSERT(checkTintShade(0xff, 0xff, 0xff, "ffffff", -5000, "808080"));
+ // 100% shade
+ CPPUNIT_ASSERT(checkTintShade(0xff, 0xff, 0xff, "ffffff", -10000, "000000"));
+
+ // GREY reference
+
+ // 0% - no change
+ CPPUNIT_ASSERT(checkTintShade(0x80, 0x80, 0x80, "808080", 0, "808080"));
+
+ // 25% tint
+ CPPUNIT_ASSERT(checkTintShade(0x80, 0x80, 0x80, "808080", 2500, "a0a0a0"));
+ // 50% tint
+ CPPUNIT_ASSERT(checkTintShade(0x80, 0x80, 0x80, "808080", 5000, "c0c0c0"));
+ // 100% tint
+ CPPUNIT_ASSERT(checkTintShade(0x80, 0x80, 0x80, "808080", 10000, "ffffff"));
+
+ // 25% shade
+ CPPUNIT_ASSERT(checkTintShade(0x80, 0x80, 0x80, "808080", -2500, "606060"));
+ // 50% shade
+ CPPUNIT_ASSERT(checkTintShade(0x80, 0x80, 0x80, "808080", -5000, "404040"));
+ // 100% shade
+ CPPUNIT_ASSERT(checkTintShade(0x80, 0x80, 0x80, "808080", -10000, "000000"));
+
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
}
diff --git a/tools/source/generic/color.cxx b/tools/source/generic/color.cxx
index 07fdd00fd7c4..4ab32d471ea1 100644
--- a/tools/source/generic/color.cxx
+++ b/tools/source/generic/color.cxx
@@ -312,6 +312,32 @@ SvStream& ReadColor( SvStream& rIStream, Color& rColor )
return rIStream;
}
+void Color::ApplyTintOrShade(sal_Int16 n100thPercent)
+{
+ if (n100thPercent == 0)
+ return;
+
+ basegfx::BColor aBColor = basegfx::tools::rgb2hsl(getBColor());
+ double fFactor = 1.0 - (std::abs(double(n100thPercent)) / 10000.0);
+ double fResult;
+
+ if (n100thPercent > 0) // tint
+ {
+ fResult = aBColor.getBlue() * fFactor + (1.0 - fFactor);
+ }
+ else if (n100thPercent < 0) // shade
+ {
+ fResult = aBColor.getBlue() * fFactor;
+ }
+
+ aBColor.setBlue(fResult);
+ aBColor = basegfx::tools::hsl2rgb(aBColor);
+
+ SetRed(sal_uInt8(( aBColor.getRed() * 255.0) + 0.5));
+ SetGreen(sal_uInt8((aBColor.getGreen() * 255.0) + 0.5));
+ SetBlue(sal_uInt8(( aBColor.getBlue() * 255.0) + 0.5));
+}
+
SvStream& WriteColor( SvStream& rOStream, const Color& rColor )
{
DBG_ASSERTWARNING( rOStream.GetVersion(), "Color::<< - Solar-Version not set on rOStream" );