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);
         }
     }
 }

Reply via email to