[Libreoffice-commits] core.git: include/oox oox/source sd/qa

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Jul 2 07:07:34 UTC 2019


 include/oox/export/drawingml.hxx    |    9 +++++--
 oox/source/export/drawingml.cxx     |   43 ++++++++++++++++++++++++++++++------
 sd/qa/unit/data/pptx/tdf125554.pptx |binary
 sd/qa/unit/export-tests-ooxml1.cxx  |   19 +++++++++++++++
 4 files changed, 63 insertions(+), 8 deletions(-)

New commits:
commit 599ae1151bf893491db7ad983d64c77521c3ae9d
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Jul 1 21:10:01 2019 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Jul 2 09:06:37 2019 +0200

    tdf#125554 PPTX export: handle gradient transparency for gradient fill
    
    Regression from commit cfc1f4ea4889f768d689a0df71519e9bcb707bc0 (oox:
    disable gradient fill grab-bag for PPTX, 2019-02-05), the problem was
    that in the past grab-bag roundtrip worked (in some cases) for this
    shape fill case, but true roundtrip did not.
    
    So when the commit disabled grab-bags (since their color pointers in the
    theme don't work in the PPTX case), a previously not implemented feature
    now started causing a real problem.
    
    Fix the bug by adding support for transparent linear gradients on the
    exports side. This means that in case the import creates both a fill
    gradient and a transparency gradient, then now the export creates markup
    based on both, not only based on the fill gradient.
    
    Change-Id: I99fa3caba2b2884c2acb7e0704bbeb0b6cffd4a4
    Reviewed-on: https://gerrit.libreoffice.org/74968
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index d74c82ff8b28..55279e2de69f 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -183,7 +183,7 @@ public:
     void WriteColor( ::Color nColor, sal_Int32 nAlpha = MAX_PERCENT );
     void WriteColor( const OUString& sColorSchemeName, const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
     void WriteColorTransformations( const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
-    void WriteGradientStop( sal_uInt16 nStop, ::Color nColor );
+    void WriteGradientStop(sal_uInt16 nStop, ::Color nColor, sal_Int32 nAlpha = MAX_PERCENT);
     void WriteLineArrow( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet, bool bLineStart );
     void WriteConnectorConnections( EscherConnectorListEntry& rConnectorEntry, sal_Int32 nStartID, sal_Int32 nEndID );
 
@@ -191,7 +191,12 @@ public:
     void WriteSolidFill( const OUString& sSchemeName, const css::uno::Sequence< css::beans::PropertyValue >& aTransformations, sal_Int32 nAlpha = MAX_PERCENT );
     void WriteSolidFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
     void WriteGradientFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet );
-    void WriteGradientFill( css::awt::Gradient rGradient );
+
+    /// In case rXPropSet is set, it may serve as a source of gradient transparency information.
+    void WriteGradientFill(css::awt::Gradient rGradient,
+                           const css::uno::Reference<css::beans::XPropertySet>& rXPropSet
+                           = css::uno::Reference<css::beans::XPropertySet>());
+
     void WriteGrabBagGradientFill( const css::uno::Sequence< css::beans::PropertyValue >& aGradientStops, css::awt::Gradient rGradient);
 
     void WriteBlipOrNormalFill( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet,
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 11d900e28794..08cbf8b796fd 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -132,6 +132,17 @@ using ::css::io::XOutputStream;
 using ::sax_fastparser::FSHelperPtr;
 using ::sax_fastparser::FastSerializerHelper;
 
+namespace
+{
+/// Extracts start or end alpha information from a transparency gradient.
+sal_Int32 GetAlphaFromTransparenceGradient(const awt::Gradient& rGradient, bool bStart)
+{
+    // Our alpha is a gray color value.
+    sal_uInt8 nRed = ::Color(bStart ? rGradient.StartColor : rGradient.EndColor).GetRed();
+    // drawingML alpha is a percentage on a 0..100000 scale.
+    return (255 - nRed) * oox::drawingml::MAX_PERCENT / 255;
+}
+}
 
 namespace oox {
 namespace drawingml {
@@ -415,10 +426,10 @@ void DrawingML::WriteSolidFill( const Reference< XPropertySet >& rXPropSet )
     }
 }
 
-void DrawingML::WriteGradientStop( sal_uInt16 nStop, ::Color nColor )
+void DrawingML::WriteGradientStop(sal_uInt16 nStop, ::Color nColor, sal_Int32 nAlpha)
 {
     mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(nStop * 1000));
-    WriteColor( nColor );
+    WriteColor(nColor, nAlpha);
     mpFS->endElementNS( XML_a, XML_gs );
 }
 
@@ -480,7 +491,7 @@ void DrawingML::WriteGradientFill( const Reference< XPropertySet >& rXPropSet )
         else
         {
             mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape, "0");
-            WriteGradientFill(aGradient);
+            WriteGradientFill(aGradient, rXPropSet);
             mpFS->endElementNS( XML_a, XML_gradFill );
         }
     }
@@ -545,20 +556,40 @@ void DrawingML::WriteGrabBagGradientFill( const Sequence< PropertyValue >& aGrad
     }
 }
 
-void DrawingML::WriteGradientFill( awt::Gradient rGradient )
+void DrawingML::WriteGradientFill(awt::Gradient rGradient,
+                                  const uno::Reference<beans::XPropertySet>& rXPropSet)
 {
     switch( rGradient.Style )
     {
         default:
         case awt::GradientStyle_LINEAR:
+        {
+            awt::Gradient aTransparenceGradient;
+            bool bTransparent = false;
+            if (rXPropSet.is() && GetProperty(rXPropSet, "FillTransparenceGradient"))
+            {
+                aTransparenceGradient = *o3tl::doAccess<awt::Gradient>(mAny);
+                bTransparent = true;
+            }
+
             mpFS->startElementNS(XML_a, XML_gsLst);
-            WriteGradientStop( 0, ColorWithIntensity( rGradient.StartColor, rGradient.StartIntensity ) );
-            WriteGradientStop( 100, ColorWithIntensity( rGradient.EndColor, rGradient.EndIntensity ) );
+            sal_Int32 nStartAlpha = MAX_PERCENT;
+            sal_Int32 nEndAlpha = MAX_PERCENT;
+            if (bTransparent)
+            {
+                nStartAlpha = GetAlphaFromTransparenceGradient(aTransparenceGradient, true);
+                nEndAlpha = GetAlphaFromTransparenceGradient(aTransparenceGradient, false);
+            }
+            WriteGradientStop(0, ColorWithIntensity(rGradient.StartColor, rGradient.StartIntensity),
+                              nStartAlpha);
+            WriteGradientStop(100, ColorWithIntensity(rGradient.EndColor, rGradient.EndIntensity),
+                              nEndAlpha);
             mpFS->endElementNS( XML_a, XML_gsLst );
             mpFS->singleElementNS(
                 XML_a, XML_lin, XML_ang,
                 OString::number((((3600 - rGradient.Angle + 900) * 6000) % 21600000)));
             break;
+        }
 
         case awt::GradientStyle_AXIAL:
             mpFS->startElementNS(XML_a, XML_gsLst);
diff --git a/sd/qa/unit/data/pptx/tdf125554.pptx b/sd/qa/unit/data/pptx/tdf125554.pptx
new file mode 100644
index 000000000000..b78bc43fa98b
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf125554.pptx differ
diff --git a/sd/qa/unit/export-tests-ooxml1.cxx b/sd/qa/unit/export-tests-ooxml1.cxx
index d45b58b89504..a3df821e1bf0 100644
--- a/sd/qa/unit/export-tests-ooxml1.cxx
+++ b/sd/qa/unit/export-tests-ooxml1.cxx
@@ -109,6 +109,7 @@ public:
     void testCustomXml();
     void testTdf94238();
     void testPictureTransparency();
+    void testTdf125554();
 
     CPPUNIT_TEST_SUITE(SdOOXMLExportTest1);
 
@@ -140,6 +141,7 @@ public:
     CPPUNIT_TEST(testTdf112633);
     CPPUNIT_TEST(testCustomXml);
     CPPUNIT_TEST(testTdf94238);
+    CPPUNIT_TEST(testTdf125554);
     CPPUNIT_TEST(testPictureTransparency);
 
     CPPUNIT_TEST_SUITE_END();
@@ -913,6 +915,23 @@ void SdOOXMLExportTest1::testPictureTransparency()
     xDocShRef->DoClose();
 }
 
+void SdOOXMLExportTest1::testTdf125554()
+{
+    ::sd::DrawDocShellRef xDocShRef
+        = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf125554.pptx"), PPTX);
+    xDocShRef = saveAndReload(xDocShRef.get(), PPTX);
+
+    uno::Reference<beans::XPropertySet> xShape = getShapeFromPage(0, 0, xDocShRef);
+    uno::Any aFillTransparenceGradientName
+        = xShape->getPropertyValue("FillTransparenceGradientName");
+    CPPUNIT_ASSERT(aFillTransparenceGradientName.has<OUString>());
+    // Without the accompanying fix in place, this test would have failed, i.e. the transparency of
+    // the shape has no gradient, so it looked like a solid fill instead of a gradient fill.
+    CPPUNIT_ASSERT(!aFillTransparenceGradientName.get<OUString>().isEmpty());
+
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest1);
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list