include/oox/export/drawingml.hxx     |    2 +
 oox/qa/unit/data/refer-to-theme.pptx |binary
 oox/qa/unit/export.cxx               |   19 ++++++++++++
 oox/source/export/drawingml.cxx      |   54 ++++++++++++++++++++++++++++++++++-
 4 files changed, 74 insertions(+), 1 deletion(-)

New commits:
commit 05f8da6afc3c83eefd06f91cd7a2bc91a84ef8ea
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Dec 2 08:45:26 2021 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Jun 27 08:59:16 2022 +0200

    PPTX export: handle theme colors from the doc model for shape text
    
    As a start, do this only in case there are no effects used. If there is
    no theme color or there are effects, fall back to the old code.
    
    Also move parseExportStream() from SdModelTestBaseXML up to MacrosTest,
    so oox/ test code can use it as well.
    
    (cherry picked from commit f36767fde87191258ea21f3faac0be6ad79328e0)
    
    Conflicts:
            oox/qa/unit/export.cxx
    
    Change-Id: Ia76581dcef110341f6c3e60f22c34818ed0dcabc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136394
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index dc01e20f9199..b15bf9d81aba 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -229,6 +229,8 @@ public:
     void WriteLineArrow( const css::uno::Reference< css::beans::XPropertySet 
>& rXPropSet, bool bLineStart );
     void WriteConnectorConnections( EscherConnectorListEntry& rConnectorEntry, 
sal_Int32 nStartID, sal_Int32 nEndID );
 
+    bool WriteCharColor(const css::uno::Reference<css::beans::XPropertySet>& 
xPropertySet);
+
     void WriteSolidFill( ::Color nColor, sal_Int32 nAlpha = MAX_PERCENT );
     void WriteSolidFill( const OUString& sSchemeName, const 
css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 
nAlpha = MAX_PERCENT );
     void WriteSolidFill( const ::Color nColor, const css::uno::Sequence< 
css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
diff --git a/oox/qa/unit/data/refer-to-theme.pptx 
b/oox/qa/unit/data/refer-to-theme.pptx
new file mode 100644
index 000000000000..9a45799ab977
Binary files /dev/null and b/oox/qa/unit/data/refer-to-theme.pptx differ
diff --git a/oox/qa/unit/export.cxx b/oox/qa/unit/export.cxx
index 62988f7fd3bf..58169c558e48 100644
--- a/oox/qa/unit/export.cxx
+++ b/oox/qa/unit/export.cxx
@@ -570,6 +570,25 @@ CPPUNIT_TEST_FIXTURE(Test, testFaultyPathCommandsAWT)
     assertXPath(pXmlDoc, 
"//p:spTree/p:sp[3]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo");
     assertXPath(pXmlDoc, 
"//p:spTree/p:sp[4]/p:spPr/a:custGeom/a:pathLst/a:path/a:moveTo");
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testReferToTheme)
+{
+    // Given a PPTX file that contains references to a theme:
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"refer-to-theme.pptx";
+
+    // When saving that document:
+    loadAndSave(aURL, "Impress Office Open XML");
+
+    std::unique_ptr<SvStream> pStream = parseExportStream(getTempFile(), 
"ppt/slides/slide1.xml");
+    xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get());
+    // Then make sure the shape text color is a scheme color:
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 0
+    // - XPath '//p:sp/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr' number 
of nodes is incorrect
+    // i.e. the <a:schemeClr> element was not written.
+    assertXPath(pXmlDoc, 
"//p:sp/p:txBody/a:p/a:r/a:rPr/a:solidFill/a:schemeClr", "val", "accent1");
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index c4795cf9e5b8..45274efa9315 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -154,6 +154,21 @@ sal_Int32 GetAlphaFromTransparenceGradient(const 
awt::Gradient& rGradient, bool
     // drawingML alpha is a percentage on a 0..100000 scale.
     return (255 - nRed) * oox::drawingml::MAX_PERCENT / 255;
 }
+
+const char* g_aPredefinedClrNames[] = {
+    "dk1",
+    "lt1",
+    "dk2",
+    "lt2",
+    "accent1",
+    "accent2",
+    "accent3",
+    "accent4",
+    "accent5",
+    "accent6",
+    "hlink",
+    "folHlink",
+};
 }
 
 namespace oox::drawingml {
@@ -402,6 +417,40 @@ void DrawingML::WriteColorTransformations( const Sequence< 
PropertyValue >& aTra
     }
 }
 
+bool DrawingML::WriteCharColor(const 
css::uno::Reference<css::beans::XPropertySet>& xPropertySet)
+{
+    if 
(!xPropertySet->getPropertySetInfo()->hasPropertyByName("CharColorTheme"))
+    {
+        return false;
+    }
+
+    sal_Int32 nCharColorTheme = -1;
+    xPropertySet->getPropertyValue("CharColorTheme") >>= nCharColorTheme;
+    if (nCharColorTheme < 0 || nCharColorTheme > 11)
+    {
+        return false;
+    }
+
+    const char* pColorName = g_aPredefinedClrNames[nCharColorTheme];
+
+    sal_Int32 nCharColorLumMod{};
+    xPropertySet->getPropertyValue("CharColorLumMod") >>= nCharColorLumMod;
+    sal_Int32 nCharColorLumOff{};
+    xPropertySet->getPropertyValue("CharColorLumOff") >>= nCharColorLumOff;
+    sal_Int32 nCharColorTintOrShade{};
+    xPropertySet->getPropertyValue("CharColorTintOrShade") >>= 
nCharColorTintOrShade;
+    if (nCharColorLumMod != 10000 || nCharColorLumOff != 0 || 
nCharColorTintOrShade != 0)
+    {
+        return false;
+    }
+
+    mpFS->startElementNS(XML_a, XML_solidFill);
+    mpFS->singleElementNS(XML_a, XML_schemeClr, XML_val, pColorName);
+    mpFS->endElementNS(XML_a, XML_solidFill);
+
+    return true;
+}
+
 void DrawingML::WriteSolidFill( ::Color nColor, sal_Int32 nAlpha )
 {
     mpFS->startElementNS(XML_a, XML_solidFill);
@@ -2160,7 +2209,10 @@ void DrawingML::WriteRunProperties( const Reference< 
XPropertySet >& rRun, bool
             {
                 color.SetAlpha(255);
                 // TODO: special handle embossed/engraved
-                WriteSolidFill(color, nTransparency);
+                if (!WriteCharColor(rXPropSet))
+                {
+                    WriteSolidFill(color, nTransparency);
+                }
             }
         }
     }

Reply via email to