oox/qa/unit/data/gradient-multistep-transparency.pptx |binary
 oox/qa/unit/drawingml.cxx                             |   27 +++++++++++++
 oox/source/drawingml/fillproperties.cxx               |   36 ++++++++++++++++--
 3 files changed, 60 insertions(+), 3 deletions(-)

New commits:
commit 73993fdb5d4b507694cd0edf80887d19f7e2bf9a
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Aug 6 12:31:35 2020 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Aug 6 13:25:19 2020 +0200

    tdf#134183 PPTX: improve import of transparency in multi-step gradients
    
    Impress core only support a single step, improve the conversion from
    multi-step to single step to take transparency into account explicitly.
    
    Once we select the widest segment, look backwards and forward if there
    are other next segments which have the same RGB color, just different
    transparency and include them. This helps in general, because in case a
    0% or 100% transparency is mishandled, that's very visible.
    
    Change-Id: I11d593c01a6a4b16149ce74c1408c2a39895e941
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100231
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/oox/qa/unit/data/gradient-multistep-transparency.pptx 
b/oox/qa/unit/data/gradient-multistep-transparency.pptx
new file mode 100644
index 000000000000..83946c71b403
Binary files /dev/null and 
b/oox/qa/unit/data/gradient-multistep-transparency.pptx differ
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index ee5ae764af70..d88f91797304 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -10,7 +10,9 @@
 #include <test/bootstrapfixture.hxx>
 #include <unotest/macros_test.hxx>
 
+#include <com/sun/star/awt/Gradient.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
 #include <com/sun/star/drawing/FillStyle.hpp>
 #include <com/sun/star/drawing/XShape.hpp>
@@ -199,6 +201,31 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, 
testChartDataLabelCharColor)
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xffffff), nCharColor);
 }
 
+CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testGradientMultiStepTransparency)
+{
+    // Load a document with a multi-step gradient.
+    OUString aURL
+        = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"gradient-multistep-transparency.pptx";
+    load(aURL);
+
+    // Check the end transparency of the gradient.
+    uno::Reference<drawing::XDrawPagesSupplier> 
xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> 
xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
+    uno::Reference<container::XNamed> xShape(xDrawPage->getByIndex(1), 
uno::UNO_QUERY);
+    CPPUNIT_ASSERT_EQUAL(OUString("Rectangle 4"), xShape->getName());
+    uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
+    awt::Gradient aTransparence;
+    xShapeProps->getPropertyValue("FillTransparenceGradient") >>= 
aTransparence;
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 16777215 (0xffffff)
+    // - Actual  : 3487029 (0x353535)
+    // i.e. the end transparency was not 100%, but was 21%, leading to an 
unexpected visible line on
+    // the right of this shape.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xffffff), 
aTransparence.EndColor);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/fillproperties.cxx 
b/oox/source/drawingml/fillproperties.cxx
index f203e9e2823e..7082cbee0186 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -512,21 +512,51 @@ void FillProperties::pushToPropMap( ShapePropertyMap& 
rPropMap,
                     // convert DrawingML angle (in 1/60000 degrees) to API 
angle (in 1/10 degrees)
                     aGradient.Angle = static_cast< sal_Int16 >( (8100 - 
(nDmlAngle / (PER_DEGREE / 10))) % 3600 );
                     Color aStartColor, aEndColor;
+
+                    // Try to grow the widest segment backwards: if a previous 
segment has the same
+                    // color, just different transparency, include it.
+                    while (aWidestSegmentStart != aGradientStops.begin())
+                    {
+                        auto it = std::prev(aWidestSegmentStart);
+                        if (it->second.getColor(rGraphicHelper, nPhClr)
+                            != 
aWidestSegmentStart->second.getColor(rGraphicHelper, nPhClr))
+                        {
+                            break;
+                        }
+
+                        aWidestSegmentStart = it;
+                    }
+
+                    auto aWidestSegmentEnd = std::next(aWidestSegmentStart);
+                    // Try to grow the widest segment forward: if a neext 
segment has the same
+                    // color, just different transparency, include it.
+                    while (aWidestSegmentEnd != 
std::prev(aGradientStops.end()))
+                    {
+                        auto it = std::next(aWidestSegmentEnd);
+                        if (it->second.getColor(rGraphicHelper, nPhClr)
+                            != 
aWidestSegmentEnd->second.getColor(rGraphicHelper, nPhClr))
+                        {
+                            break;
+                        }
+
+                        aWidestSegmentEnd = it;
+                    }
+
                     if( bSymmetric )
                     {
-                        aStartColor = std::next(aWidestSegmentStart)->second;
+                        aStartColor = aWidestSegmentEnd->second;
                         aEndColor = aWidestSegmentStart->second;
                         nBorder *= 2;
                     }
                     else if( bSwap )
                     {
-                        aStartColor = std::next(aWidestSegmentStart)->second;
+                        aStartColor = aWidestSegmentEnd->second;
                         aEndColor = aWidestSegmentStart->second;
                     }
                     else
                     {
                         aStartColor = aWidestSegmentStart->second;
-                        aEndColor = std::next(aWidestSegmentStart)->second;
+                        aEndColor = aWidestSegmentEnd->second;
                     }
 
                     SAL_INFO("oox.drawingml.gradient", "start color: " << 
std::hex << sal_Int32(aStartColor.getColor( rGraphicHelper, nPhClr )) << 
std::dec <<
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to