svx/qa/unit/data/theme.pptx |binary svx/qa/unit/styles.cxx | 49 ++++++++++++++++++++++++---------------- svx/source/styles/ColorSets.cxx | 42 ++++++++++++++++++++++++++-------- 3 files changed, 63 insertions(+), 28 deletions(-)
New commits: commit 9ebf7034c9cd3a0601542397254ebc97647a862e Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Dec 3 08:38:18 2021 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Fri Dec 3 13:34:58 2021 +0100 svx: consider color effects when updating objects for theme changes This builds on top of commit 48f0c5f73f99c919ec24deadc96c3cf5483c9314 (svx: update objects of pages of a master page when the theme changes, 2021-11-30), but now not only plain colors with colors with effects are also considered. The luminance modulation / offset is what PowerPoint uses the generate lighter / darker variants, tinting / shading is what Word uses. Change-Id: Ibfafb9be9986645117015bf3b05491daec8914be Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126270 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/svx/qa/unit/data/theme.pptx b/svx/qa/unit/data/theme.pptx index 397b6706ffa4..652a9fc29e06 100644 Binary files a/svx/qa/unit/data/theme.pptx and b/svx/qa/unit/data/theme.pptx differ diff --git a/svx/qa/unit/styles.cxx b/svx/qa/unit/styles.cxx index 9cbae8f997ba..1e7151edf359 100644 --- a/svx/qa/unit/styles.cxx +++ b/svx/qa/unit/styles.cxx @@ -49,6 +49,19 @@ void Test::tearDown() constexpr OUStringLiteral DATA_DIRECTORY = u"/svx/qa/unit/data/"; +/// Get the character color of the first text portion in xShape. +sal_Int32 GetShapeTextColor(const uno::Reference<text::XTextRange>& xShape) +{ + uno::Reference<container::XEnumerationAccess> xText(xShape->getText(), uno::UNO_QUERY); + uno::Reference<container::XEnumerationAccess> xPara(xText->createEnumeration()->nextElement(), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xPortion(xPara->createEnumeration()->nextElement(), + uno::UNO_QUERY); + sal_Int32 nColor{}; + xPortion->getPropertyValue("CharColor") >>= nColor; + return nColor; +} + CPPUNIT_TEST_FIXTURE(Test, testThemeChange) { // Given a document, with a first slide and blue shape text from theme: @@ -59,17 +72,14 @@ CPPUNIT_TEST_FIXTURE(Test, testThemeChange) xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference<drawing::XShapes> xDrawPageShapes(xDrawPage, uno::UNO_QUERY); uno::Reference<text::XTextRange> xShape(xDrawPageShapes->getByIndex(0), uno::UNO_QUERY); - { - uno::Reference<container::XEnumerationAccess> xText(xShape->getText(), uno::UNO_QUERY); - uno::Reference<container::XEnumerationAccess> xPara( - xText->createEnumeration()->nextElement(), uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xPortion(xPara->createEnumeration()->nextElement(), - uno::UNO_QUERY); - sal_Int32 nColor{}; - xPortion->getPropertyValue("CharColor") >>= nColor; - // Blue. - CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x4472c4), nColor); - } + // Blue. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x4472c4), GetShapeTextColor(xShape)); + uno::Reference<text::XTextRange> xShape2(xDrawPageShapes->getByIndex(1), uno::UNO_QUERY); + // Blue, lighter. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xb4c7e7), GetShapeTextColor(xShape2)); + uno::Reference<text::XTextRange> xShape3(xDrawPageShapes->getByIndex(2), uno::UNO_QUERY); + // Blue, darker. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x2f5597), GetShapeTextColor(xShape3)); // When changing the master slide of slide 1 to use the theme of the second master slide: uno::Reference<drawing::XMasterPageTarget> xDrawPage2( @@ -80,18 +90,19 @@ CPPUNIT_TEST_FIXTURE(Test, testThemeChange) xMasterPage->setPropertyValue("Theme", aTheme); // Then make sure the shape text color is now green: - uno::Reference<container::XEnumerationAccess> xText(xShape->getText(), uno::UNO_QUERY); - uno::Reference<container::XEnumerationAccess> xPara(xText->createEnumeration()->nextElement(), - uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xPortion(xPara->createEnumeration()->nextElement(), - uno::UNO_QUERY); - sal_Int32 nColor{}; - xPortion->getPropertyValue("CharColor") >>= nColor; // Without the accompanying fix in place, this test would have failed with: // - Expected: 9486886 (#90c226, green) // - Actual : 4485828 (#4472c4, blue) // i.e. shape text was not updated on theme change. - CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x90c226), nColor); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x90c226), GetShapeTextColor(xShape)); + // Green, lighter: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 14020002 (#d5eda2, light green) + // - Actual : 9486886 (#90c226, stock green) + // i.e. the "light" effect on green was not applied. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xd5eda2), GetShapeTextColor(xShape2)); + // Green, darker. + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x6c911d), GetShapeTextColor(xShape3)); } } diff --git a/svx/source/styles/ColorSets.cxx b/svx/source/styles/ColorSets.cxx index a5f8c6e7c548..30a9dd423d78 100644 --- a/svx/source/styles/ColorSets.cxx +++ b/svx/source/styles/ColorSets.cxx @@ -33,6 +33,38 @@ using namespace com::sun::star; namespace { +/// Updates a text portion to match a new color set, in case it already uses theme colors. +void UpdateTextPortionColorSet(const uno::Reference<beans::XPropertySet>& xPortion, + svx::ColorSet& rColorSet) +{ + sal_Int16 nCharColorTheme = -1; + xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_THEME) >>= nCharColorTheme; + if (nCharColorTheme < 0 || nCharColorTheme > 11) + { + return; + } + + Color aColor = rColorSet.getColor(nCharColorTheme); + sal_Int32 nCharColorLumMod{}; + xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_LUM_MOD) >>= nCharColorLumMod; + sal_Int32 nCharColorLumOff{}; + xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_LUM_OFF) >>= nCharColorLumOff; + if (nCharColorLumMod != 10000 || nCharColorLumOff != 0) + { + aColor.ApplyLumModOff(nCharColorLumMod, nCharColorLumOff); + } + + sal_Int32 nCharColorTintOrShade{}; + xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_TINT_OR_SHADE) >>= nCharColorTintOrShade; + if (nCharColorTintOrShade != 0) + { + aColor.ApplyTintOrShade(nCharColorTintOrShade); + } + + xPortion->setPropertyValue(UNO_NAME_EDIT_CHAR_COLOR, + uno::makeAny(static_cast<sal_Int32>(aColor))); +} + void UpdateSdrObject(svx::Theme* pTheme, SdrObject* pObject) { svx::ColorSet* pColorSet = pTheme->GetColorSet(); @@ -51,15 +83,7 @@ void UpdateSdrObject(svx::Theme* pTheme, SdrObject* pObject) while (xPortions->hasMoreElements()) { uno::Reference<beans::XPropertySet> xPortion(xPortions->nextElement(), uno::UNO_QUERY); - sal_Int16 nCharColorTheme = -1; - xPortion->getPropertyValue(UNO_NAME_EDIT_CHAR_COLOR_THEME) >>= nCharColorTheme; - if (nCharColorTheme < 0 || nCharColorTheme > 11) - { - continue; - } - - Color aColor = pColorSet->getColor(nCharColorTheme); - xPortion->setPropertyValue(UNO_NAME_EDIT_CHAR_COLOR, uno::makeAny(static_cast<sal_Int32>(aColor))); + UpdateTextPortionColorSet(xPortion, *pColorSet); } } }