summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-11-29 08:28:28 +0100
committerMiklos Vajna <vmiklos@collabora.com>2022-06-27 08:58:25 +0200
commitbad177d0604b76672af2612cf8ab39f8e8345dc7 (patch)
treef08ea25ab3270d85046e32097b63895682580eaa /tools
parent4ed228b81d9d051addda86a4394ed2ad878cf34d (diff)
tools Color: implement MSO-style luminance modulation/offset filter
To be used when a filtered theme color will be applied on the UI, and not at PPTX import time. (cherry picked from commit 8662293d17a875f4389ea21be00e768e3de3d048) Change-Id: Ifb56e38e59b529ef436063c407ee156d76a77f9c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136371 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/qa/cppunit/test_color.cxx13
-rw-r--r--tools/source/generic/color.cxx32
2 files changed, 45 insertions, 0 deletions
diff --git a/tools/qa/cppunit/test_color.cxx b/tools/qa/cppunit/test_color.cxx
index f3ffd9c692cd..3dd4225cb20f 100644
--- a/tools/qa/cppunit/test_color.cxx
+++ b/tools/qa/cppunit/test_color.cxx
@@ -22,6 +22,7 @@ public:
void testVariables();
void test_asRGBColor();
void test_ApplyTintOrShade();
+ void test_ApplyLumModOff();
void testGetColorError();
void testInvert();
void testBColor();
@@ -31,6 +32,7 @@ public:
CPPUNIT_TEST(testVariables);
CPPUNIT_TEST(test_asRGBColor);
CPPUNIT_TEST(test_ApplyTintOrShade);
+ CPPUNIT_TEST(test_ApplyLumModOff);
CPPUNIT_TEST(testGetColorError);
CPPUNIT_TEST(testInvert);
CPPUNIT_TEST(testBColor);
@@ -163,6 +165,17 @@ void Test::test_ApplyTintOrShade()
CPPUNIT_ASSERT_EQUAL(OUString("000000"), createTintShade(0x80, 0x80, 0x80, u"808080", -10000));
}
+void Test::test_ApplyLumModOff()
+{
+ // Kind of blue.
+ Color aColor(0x44, 0x72, 0xC4);
+
+ // PowerPoint calls this "Ligher 40%".
+ aColor.ApplyLumModOff(6000, 4000);
+
+ CPPUNIT_ASSERT_EQUAL(OUString("8faadc"), aColor.AsRGBHexString());
+}
+
void Test::testGetColorError()
{
CPPUNIT_ASSERT_EQUAL(sal_uInt16(0), Color(0xAA, 0xBB, 0xCC).GetColorError(Color(0xAA, 0xBB, 0xCC)));
diff --git a/tools/source/generic/color.cxx b/tools/source/generic/color.cxx
index cf4e084b722f..5df32719eb2c 100644
--- a/tools/source/generic/color.cxx
+++ b/tools/source/generic/color.cxx
@@ -230,4 +230,36 @@ void Color::ApplyTintOrShade(sal_Int16 n100thPercent)
B = sal_uInt8(std::lround(aBColor.getBlue() * 255.0));
}
+void Color::ApplyLumModOff(sal_Int16 nMod, sal_Int16 nOff)
+{
+ if (nMod == 10000 && nOff == 0)
+ {
+ return;
+ }
+ // Switch to HSL, where applying these transforms is easier.
+ basegfx::BColor aBColor = basegfx::utils::rgb2hsl(getBColor());
+
+ // 50% is half luminance, 200% is double luminance. Unit is 100th percent.
+ aBColor.setBlue(std::clamp(aBColor.getBlue() * nMod / 10000, 0.0, 1.0));
+ // If color changes to black or white, it will stay gray if luminance changes again.
+ if ((aBColor.getBlue() == 0.0) || (aBColor.getBlue() == 1.0))
+ {
+ aBColor.setGreen(0.0);
+ }
+
+ // Luminance offset means hue and saturation is left unchanged. Unit is 100th percent.
+ aBColor.setBlue(std::clamp(aBColor.getBlue() + static_cast<double>(nOff) / 10000, 0.0, 1.0));
+ // If color changes to black or white, it will stay gray if luminance changes again.
+ if ((aBColor.getBlue() == 0.0) || (aBColor.getBlue() == 1.0))
+ {
+ aBColor.setGreen(0.0);
+ }
+
+ // Switch back to RGB.
+ aBColor = basegfx::utils::hsl2rgb(aBColor);
+ R = sal_uInt8(std::lround(aBColor.getRed() * 255.0));
+ G = sal_uInt8(std::lround(aBColor.getGreen() * 255.0));
+ B = sal_uInt8(std::lround(aBColor.getBlue() * 255.0));
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */