diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2021-11-29 08:28:28 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2021-11-29 09:51:16 +0100 |
commit | 8662293d17a875f4389ea21be00e768e3de3d048 (patch) | |
tree | 6c5d54c67efe3612bcdf63fe6a23f79cacf213f8 /tools | |
parent | 41cc1d2c0c0c3bfa5ba341311f68df05375859fb (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.
Change-Id: Ifb56e38e59b529ef436063c407ee156d76a77f9c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126011
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qa/cppunit/test_color.cxx | 13 | ||||
-rw-r--r-- | tools/source/generic/color.cxx | 32 |
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: */ |