diff options
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: */ |