tdf#136059 OOXML export: fix shape wrap "Contour"

Custom shapes lost their contour setting, e.g. the
text was wrapped around the bounding box of a diamond
instead of the shape.

Change-Id: Ic1e276b8957751aad95cc2624e9f54dcb853ddad
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108930
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf136059.odt b/sw/qa/extras/ooxmlexport/data/tdf136059.odt
new file mode 100755
index 0000000..50d808d
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf136059.odt
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
index c35db2c..37610a2 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport16.cxx
@@ -31,6 +31,13 @@ protected:
    }
};

DECLARE_OOXMLEXPORT_TEST(testTdf136059, "tdf136059.odt")
{
    CPPUNIT_ASSERT_EQUAL_MESSAGE("Contour has not been exported!", true,
        getProperty<bool>(getShape(1), "SurroundContour"));
    // With the fix this shall pass, see tdf136059.
}

DECLARE_OOXMLEXPORT_TEST(testTdf138892_noNumbering, "tdf138892_noNumbering.docx")
{
    CPPUNIT_ASSERT_MESSAGE("Para1: Bullet point", !getProperty<OUString>(getParagraph(1), "NumberingStyleName").isEmpty());
diff --git a/sw/source/filter/ww8/docxsdrexport.cxx b/sw/source/filter/ww8/docxsdrexport.cxx
index 1af1dce..297ecf3 100644
--- a/sw/source/filter/ww8/docxsdrexport.cxx
+++ b/sw/source/filter/ww8/docxsdrexport.cxx
@@ -10,6 +10,7 @@
#include "docxsdrexport.hxx"
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
#include <editeng/lrspitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/shaditem.hxx>
@@ -34,6 +35,8 @@
#include <frmfmt.hxx>
#include <IDocumentDrawModelAccess.hxx>

#include <tools/diagnose_ex.h>

using namespace com::sun::star;
using namespace oox;

@@ -792,6 +795,77 @@ void DocxSdrExport::startDMLAnchorInline(const SwFrameFormat* pFrameFormat, cons
                m_pImpl->getSerializer()->endElementNS(XML_wp, nWrapToken);
            }
        }
        else
        {
            // In this case we likely had an odt document to be exported to docx.
            // There is no grab-bag or something else so for a workaround,
            // let's export the geometry of the shape...
            // First get the UNO-shape
            uno::Reference<drawing::XShape> xShape(
                const_cast<SdrObject*>(pFrameFormat->FindRealSdrObject())->getUnoShape(),
                uno::UNO_QUERY);

            if (xShape && xShape->getShapeType() == u"com.sun.star.drawing.CustomShape")
            {
                try
                {
                    // Get the properties of the Xshape
                    uno::Reference<beans::XPropertySet> XProps(xShape, uno::UNO_QUERY);
                    // Get the "CustomShapeGeometry" property and from its Any() make a hashMap
                    comphelper::SequenceAsHashMap aCustomShapeGeometry(
                        XProps->getPropertyValue("CustomShapeGeometry"));
                    // Get the "Path" property and from its Any() make a hashMap
                    comphelper::SequenceAsHashMap aPath(aCustomShapeGeometry.getValue("Path"));
                    // From the Any() of the "Coordinates" property get the points
                    uno::Sequence<css::drawing::EnhancedCustomShapeParameterPair> aCoords
                        = aPath.getValue("Coordinates")
                              .get<uno::Sequence<css::drawing::EnhancedCustomShapeParameterPair>>();

                    // Check if only one side wrap allowed
                    OUString sWrapType;
                    switch (pFrameFormat->GetSurround().GetSurround())
                    {
                        case text::WrapTextMode_DYNAMIC:
                            sWrapType = OUString("largest");
                            break;
                        case text::WrapTextMode_LEFT:
                            sWrapType = OUString("left");
                            break;
                        case text::WrapTextMode_RIGHT:
                            sWrapType = OUString("right");
                            break;
                        case text::WrapTextMode_PARALLEL:
                        default:
                            sWrapType = OUString("bothSides");
                            break;
                    }

                    // And export:
                    nWrapToken = XML_wrapTight;
                    m_pImpl->getSerializer()->startElementNS(XML_wp, nWrapToken, XML_wrapText,
                                                             sWrapType);

                    m_pImpl->getSerializer()->startElementNS(XML_wp, XML_wrapPolygon, XML_edited,
                                                             "0");

                    // There are the coordinates
                    for (sal_Int32 i = 0; i < aCoords.getLength(); i++)
                        m_pImpl->getSerializer()->singleElementNS(
                            XML_wp, (i == 0 ? XML_start : XML_lineTo), XML_x,
                            OString::number(aCoords[i].First.Value.get<double>()), XML_y,
                            OString::number(aCoords[i].Second.Value.get<double>()));

                    m_pImpl->getSerializer()->endElementNS(XML_wp, XML_wrapPolygon);

                    m_pImpl->getSerializer()->endElementNS(XML_wp, nWrapToken);
                }
                catch (uno::Exception& e)
                {
                    TOOLS_WARN_EXCEPTION(
                        "sw.ww8", "DocxSdrExport::startDMLAnchorInline: exeption: " << e.Message);
                }
            }
        }
    }

    // No? Then just approximate based on what we have.