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

Paul Trojahn paul.trojahn at gmail.com
Thu Aug 24 14:28:23 UTC 2017


 include/oox/export/drawingml.hxx   |    4 +-
 oox/source/export/drawingml.cxx    |   15 +++++----
 oox/source/export/shapes.cxx       |    6 ++-
 sd/qa/unit/data/odp/tdf111798.odp  |binary
 sd/qa/unit/export-tests-ooxml2.cxx |   59 +++++++++++++++++++++++++++++++++++++
 5 files changed, 74 insertions(+), 10 deletions(-)

New commits:
commit 73ee631e58f392415f23e98460ff4b2f3a763d37
Author: Paul Trojahn <paul.trojahn at gmail.com>
Date:   Thu Aug 17 20:04:27 2017 +0200

    tdf#111798 Fix deformed export of flipped custom shapes to pptx
    
    Shapes were deformed because flipping wasn't considered when removing
    the rotation. Also WriteShapeTransformation needs information about
    flipping to convert the angle correctly.
    
    Change-Id: I7d485e93c00e02b9ec6c73ad6ae2876e5bc6360a
    Reviewed-on: https://gerrit.libreoffice.org/41462
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 4ee841d33eb2..ecdad5b99b6a 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -189,8 +189,8 @@ public:
             const OUString& rURL, bool bRelPathToMedia = false , const Graphic *pGraphic=nullptr );
     void WriteBlipMode( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet, const OUString& rURL );
 
-    void WriteShapeTransformation( const css::uno::Reference< css::drawing::XShape >& rXShape,
-                  sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = false, bool bSuppressRotation = false );
+    void WriteShapeTransformation(const css::uno::Reference< css::drawing::XShape >& rXShape,
+                  sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = false, bool bSuppressRotation = false, bool bSuppressFlipping = false );
     void WriteTransformation( const tools::Rectangle& rRectangle,
                   sal_Int32 nXmlNamespace, bool bFlipH = false, bool bFlipV = false, sal_Int32 nRotation = 0 );
 
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index aec1aaecc6a5..3d5a7ace8262 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1157,11 +1157,6 @@ void DrawingML::WriteStretch( const css::uno::Reference< css::beans::XPropertySe
 void DrawingML::WriteTransformation( const tools::Rectangle& rRect,
         sal_Int32 nXmlNamespace, bool bFlipH, bool bFlipV, sal_Int32 nRotation )
 {
-    //OOXML flips shapes before rotating them.
-    if(bFlipH)
-        nRotation = nRotation * -1 + 60000*360;
-    if(bFlipV)
-        nRotation = nRotation * -1 + 60000*360;
 
     mpFS->startElementNS( nXmlNamespace, XML_xfrm,
                           XML_flipH, bFlipH ? "1" : nullptr,
@@ -1183,7 +1178,7 @@ void DrawingML::WriteTransformation( const tools::Rectangle& rRect,
     mpFS->endElementNS( nXmlNamespace, XML_xfrm );
 }
 
-void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sal_Int32 nXmlNamespace, bool bFlipH, bool bFlipV, bool bSuppressRotation  )
+void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sal_Int32 nXmlNamespace, bool bFlipH, bool bFlipV, bool bSuppressRotation, bool bSuppressFlipping )
 {
     SAL_INFO("oox.shape",  "write shape transformation");
 
@@ -1220,6 +1215,14 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa
         if (xPropertySetInfo->hasPropertyByName("RotateAngle"))
             xPropertySet->getPropertyValue("RotateAngle") >>= nRotation;
     }
+
+    // OOXML flips shapes before rotating them.
+    if(bFlipH != bFlipV)
+        nRotation = nRotation * -1 + 36000;
+
+    if(bSuppressFlipping)
+        bFlipH = bFlipV = false;
+
     WriteTransformation( tools::Rectangle( Point( aPos.X, aPos.Y ), Size( aSize.Width, aSize.Height ) ), nXmlNamespace, bFlipH, bFlipV, OOX_DRAWINGML_EXPORT_ROTATE_CLOCKWISIFY(nRotation) );
 }
 
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index b5d4a450b94b..df34231a225b 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -823,7 +823,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
 
     if (bHasHandles && bCustGeom && pShape)
     {
-        WriteShapeTransformation( xShape, XML_a ); // do not flip, polypolygon coordinates are flipped already
+        WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV, false, true );// do not flip, polypolygon coordinates are flipped already
         tools::PolyPolygon aPolyPolygon( pShape->GetLineGeometry(true) );
         sal_Int32 nRotation = 0;
         // The RotateAngle property's value is independent from any flipping, and that's exactly what we need here.
@@ -831,8 +831,10 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape )
         uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
         if (xPropertySetInfo->hasPropertyByName("RotateAngle"))
             xPropertySet->getPropertyValue("RotateAngle") >>= nRotation;
+        // Remove rotation
+        bool bInvertRotation = bFlipH != bFlipV;
         if (nRotation != 0)
-            aPolyPolygon.Rotate(Point(0,0), static_cast<sal_uInt16>(3600-nRotation/10));
+            aPolyPolygon.Rotate(Point(0,0), static_cast<sal_uInt16>(bInvertRotation ? nRotation/10 : 3600-nRotation/10));
         WritePolyPolygon( aPolyPolygon );
     }
     else if (bCustGeom)
diff --git a/sd/qa/unit/data/odp/tdf111798.odp b/sd/qa/unit/data/odp/tdf111798.odp
new file mode 100644
index 000000000000..f00c0bec7fd1
Binary files /dev/null and b/sd/qa/unit/data/odp/tdf111798.odp differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 8f41bc928427..bb66d8ebc2d1 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -99,6 +99,7 @@ public:
     void testTdf105739();
     void testPageBitmapWithTransparency();
     void testPptmContentType();
+    void testTdf111798();
     void testPptmVBAStream();
     void testTdf111518();
     void testTdf100387();
@@ -128,6 +129,7 @@ public:
     CPPUNIT_TEST(testTdf105739);
     CPPUNIT_TEST(testPageBitmapWithTransparency);
     CPPUNIT_TEST(testPptmContentType);
+    CPPUNIT_TEST(testTdf111798);
     CPPUNIT_TEST(testPptmVBAStream);
     CPPUNIT_TEST(testTdf111518);
     CPPUNIT_TEST(testTdf100387);
@@ -828,6 +830,63 @@ void SdOOXMLExportTest2::testPptmContentType()
     xDocShRef->DoClose();
 }
 
+void SdOOXMLExportTest2::testTdf111798()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/tdf111798.odp"), ODP);
+    utl::TempFile tempFile;
+    xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
+    xDocShRef->DoClose();
+    xmlDocPtr pXmlDoc = parseExport(tempFile, "ppt/slides/slide1.xml");
+
+    const OUString data[][29] =
+    {
+        {
+            "2700000", "2458080", "2414880", "1439640", "1440000",
+            "moveTo",  "0",    "3000",
+            "lnTo[1]", "3000", "3000",
+            "lnTo[2]", "3000", "4000",
+            "lnTo[3]", "4000", "2000",
+            "lnTo[4]", "3000", "0",
+            "lnTo[5]", "3000", "1000",
+            "lnTo[6]", "0",    "1000",
+            "lnTo[7]", "0",    "3000"
+        },
+        {
+            "2700000", "6778080", "2414880", "1439640", "1440000",
+            "moveTo",  "3000", "0",
+            "lnTo[1]", "3000", "3000",
+            "lnTo[2]", "4000", "3000",
+            "lnTo[3]", "2000", "4000",
+            "lnTo[4]", "0", "3000",
+            "lnTo[5]", "1000", "3000",
+            "lnTo[6]", "1000", "0",
+            "lnTo[7]", "3000", "0"
+        }
+    };
+
+    for (size_t nShapeIndex = 0; nShapeIndex < SAL_N_ELEMENTS(data); nShapeIndex++)
+    {
+        size_t nDataIndex = 0;
+
+        const OString sSpPr = "/p:sld/p:cSld/p:spTree/p:sp[" + OString::number(nShapeIndex + 1) + "]/p:spPr";
+        const OString sXfrm = sSpPr + "/a:xfrm";
+        assertXPath(pXmlDoc, sXfrm, "rot", data[nShapeIndex][nDataIndex++]);
+        const OString sOff = sXfrm + "/a:off";
+        assertXPath(pXmlDoc, sOff, "x", data[nShapeIndex][nDataIndex++]);
+        assertXPath(pXmlDoc, sOff, "y", data[nShapeIndex][nDataIndex++]);
+        const OString sExt = sXfrm + "/a:ext";
+        assertXPath(pXmlDoc, sExt, "cx", data[nShapeIndex][nDataIndex++]);
+        assertXPath(pXmlDoc, sExt, "cy", data[nShapeIndex][nDataIndex++]);
+
+        while (nDataIndex < SAL_N_ELEMENTS(data[nShapeIndex]))
+        {
+            const OString sPt = sSpPr + "/a:custGeom/a:pathLst/a:path/a:" + data[nShapeIndex][nDataIndex++].toUtf8() + "/a:pt";
+            assertXPath(pXmlDoc, sPt, "x", data[nShapeIndex][nDataIndex++]);
+            assertXPath(pXmlDoc, sPt, "y", data[nShapeIndex][nDataIndex++]);
+        }
+    }
+}
+
 void SdOOXMLExportTest2::testPptmVBAStream()
 {
     ::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptm/macro.pptm"), PPTM);


More information about the Libreoffice-commits mailing list