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

Paul Trojahn paul.trojahn at gmail.com
Sat Sep 16 15:15:04 UTC 2017


 dev/null                            |binary
 include/oox/drawingml/shape.hxx     |    2 -
 oox/source/drawingml/shape.cxx      |   49 ++++++++++++++++++++++++------------
 sd/qa/unit/data/pptx/tdf100065.pptx |binary
 sd/qa/unit/import-tests.cxx         |   49 +++++++++++-------------------------
 5 files changed, 48 insertions(+), 52 deletions(-)

New commits:
commit 33a6eb3df861009d0fe9ffee344ef00cd2906520
Author: Paul Trojahn <paul.trojahn at gmail.com>
Date:   Fri Sep 8 19:05:19 2017 +0200

    tdf#100065 PPTX Fix import of custom shapes in groups
    
    A negative scale of the parent matrix indicates that the shape needs to
    be flipped. This commit fixes text rotation as well, so
    d742c0019435d0bc90c9342492583636099a057f is no longer needed.
    
    Change-Id: I67bba34519b3af9215fe64a71f5137aa510edf7a
    Reviewed-on: https://gerrit.libreoffice.org/42250
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>

diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 7c3a8934e42a..6028a11c2bc0 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -139,7 +139,6 @@ public:
     sal_Int32                       getRotation() const { return mnRotation; }
     void                            setDiagramRotation( sal_Int32 nRotation ) { mnDiagramRotation = nRotation; }
     void                            setFlip( bool bFlipH, bool bFlipV ) { mbFlipH = bFlipH; mbFlipV = bFlipV; }
-    void                            applyParentTextFlipV(bool bTextFlipV) { mbInheritedTextFlipV = bTextFlipV; }
     void                            addChild( const ShapePtr& rChildPtr ) { maChildren.push_back( rChildPtr ); }
     std::vector< ShapePtr >&        getChildren() { return maChildren; }
 
@@ -317,7 +316,6 @@ private:
     sal_Int32                       mnDiagramRotation; // rotates shape prior to sizing, does not affect text rotation
     bool                            mbFlipH;
     bool                            mbFlipV;
-    bool                            mbInheritedTextFlipV; // Used by group shapes only
     bool                            mbHidden;
     bool                            mbHiddenMasterShape; // master shapes can be hidden in layout slides
                                                          // we need separate flag because we don't want
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 8e418d19e22a..e75f6e8ca3d1 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -116,7 +116,6 @@ Shape::Shape( const sal_Char* pServiceName, bool bDefaultHeight )
 , mnDiagramRotation( 0 )
 , mbFlipH( false )
 , mbFlipV( false )
-, mbInheritedTextFlipV(false)
 , mbHidden( false )
 , mbHiddenMasterShape( false )
 , mbLockedCanvas( false )
@@ -160,7 +159,6 @@ Shape::Shape( const ShapePtr& pSourceShape )
 , mnDiagramRotation( pSourceShape->mnDiagramRotation )
 , mbFlipH( pSourceShape->mbFlipH )
 , mbFlipV( pSourceShape->mbFlipV )
-, mbInheritedTextFlipV(pSourceShape->mbInheritedTextFlipV)
 , mbHidden( pSourceShape->mbHidden )
 , mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape )
 , mbLockedCanvas( pSourceShape->mbLockedCanvas )
@@ -317,7 +315,6 @@ void Shape::applyShapeReference( const Shape& rReferencedShape, bool bUseText )
     mnRotation = rReferencedShape.mnRotation;
     mbFlipH = rReferencedShape.mbFlipH;
     mbFlipV = rReferencedShape.mbFlipV;
-    mbInheritedTextFlipV = rReferencedShape.mbInheritedTextFlipV;
     mbHidden = rReferencedShape.mbHidden;
 }
 
@@ -391,7 +388,6 @@ void Shape::addChildren(
     std::vector< ShapePtr >::iterator aIter( rMaster.maChildren.begin() );
     while( aIter != rMaster.maChildren.end() ) {
         (*aIter)->setMasterTextListStyle( mpMasterTextListStyle );
-        (*aIter)->applyParentTextFlipV(mbInheritedTextFlipV != mbFlipV);
         (*aIter++)->addShape( rFilterBase, pTheme, rxShapes, aChildTransformation, getFillProperties(), pShapeMap );
     }
 }
@@ -492,7 +488,8 @@ Reference< XShape > const & Shape::createAndInsert(
             maSize.Height ? maSize.Height : 1.0 );
     }
 
-    if( mbFlipH || mbFlipV || mnRotation != 0)
+    bool bInGroup = !aParentTransformation.isIdentity();
+    if( mbFlipH || mbFlipV || mnRotation != 0 || bInGroup )
     {
         // calculate object's center
         basegfx::B2DPoint aCenter(0.5, 0.5);
@@ -507,30 +504,33 @@ Reference< XShape > const & Shape::createAndInsert(
             aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 );
         }
 
-        if( bUseRotationTransform && mnRotation != 0 )
+        if( bUseRotationTransform )
         {
             // OOXML flips shapes before rotating them.
-            sal_Int32 nRotation = mnRotation;
-            if(bIsCustomShape)
+            double fRotation = F_PI180 * ( (double)mnRotation / 60000.0 );
+            if( bIsCustomShape )
             {
-                if(mbFlipH)
+                basegfx::B2DVector aScale, aTranslate;
+                double fRotate, fShearX;
+                aParentTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+                // A negative scale means that the shape needs to be flipped
+                if(aScale.getX() < 0)
                 {
-                    nRotation = nRotation * -1 + 60000*360;
+                    mbFlipH = !mbFlipH;
                 }
-                if(mbFlipV)
+                if(aScale.getY() < 0)
                 {
-                    nRotation = nRotation * -1 + 60000*360;
+                    mbFlipV = !mbFlipV;
                 }
             }
             // rotate around object's center
-            aTransformation.rotate( F_PI180 * ( (double)nRotation / 60000.0 ) );
+            aTransformation.rotate( fRotation );
         }
 
         // move object back from center
         aTransformation.translate( aCenter.getX(), aCenter.getY() );
     }
 
-    bool bInGroup = !aParentTransformation.isIdentity();
     if( maPosition.X != 0 || maPosition.Y != 0)
     {
         // if global position is used, add it to transformation
@@ -544,6 +544,25 @@ Reference< XShape > const & Shape::createAndInsert(
     aParentTransformation = aTransformation;
     aTransformation.scale(1/double(EMU_PER_HMM), 1/double(EMU_PER_HMM));
 
+    if( bIsCustomShape )
+    {
+        basegfx::B2DVector aScale, aTranslate;
+        double fRotate, fShearX;
+        aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
+
+        // OOXML rotates shapes before flipping them, so the rotation needs to be inverted.
+        if( mbFlipH != mbFlipV)
+        {
+            // calculate object's center
+            basegfx::B2DPoint aCenter(0.5, 0.5);
+            aCenter *= aTransformation;
+
+            aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
+            aTransformation.rotate( fRotate * -2.0 );
+            aTransformation.translate( aCenter.getX(), aCenter.getY() );
+        }
+    }
+
     // special for lineshape
     if ( aServiceName == "com.sun.star.drawing.LineShape" )
     {
@@ -1093,8 +1112,6 @@ Reference< XShape > const & Shape::createAndInsert(
             if( getTextBody() )
             {
                 sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) );
-                if(mbInheritedTextFlipV)
-                    nTextRotateAngle -= 180 * 60000;
                 nTextRotateAngle -= mnDiagramRotation;
                 /* OOX measures text rotation clockwise in 1/60000th degrees,
                    relative to the containing shape. setTextRotateAngle wants
diff --git a/sd/qa/unit/data/pptx/tdf100065.pptx b/sd/qa/unit/data/pptx/tdf100065.pptx
new file mode 100644
index 000000000000..83952dff5504
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf100065.pptx differ
diff --git a/sd/qa/unit/data/pptx/tdf109223.pptx b/sd/qa/unit/data/pptx/tdf109223.pptx
deleted file mode 100755
index 0f68796e8e14..000000000000
Binary files a/sd/qa/unit/data/pptx/tdf109223.pptx and /dev/null differ
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 9975f16e87ef..f49fd62881ff 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -162,9 +162,9 @@ public:
     void testTdf89064();
     void testTdf108925();
     void testTdf109067();
-    void testTdf109223();
     void testTdf109187();
     void testTdf108926();
+    void testTdf100065();
 
     bool checkPattern(sd::DrawDocShellRef const & rDocRef, int nShapeNumber, std::vector<sal_uInt8>& rExpected);
     void testPatternImport();
@@ -235,9 +235,9 @@ public:
     CPPUNIT_TEST(testTdf89064);
     CPPUNIT_TEST(testTdf108925);
     CPPUNIT_TEST(testTdf109067);
-    CPPUNIT_TEST(testTdf109223);
     CPPUNIT_TEST(testTdf109187);
     CPPUNIT_TEST(testTdf108926);
+    CPPUNIT_TEST(testTdf100065);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -2234,38 +2234,6 @@ void SdImportTest::testTdf109067()
     xDocShRef->DoClose();
 }
 
-void SdImportTest::testTdf109223()
-{
-    // In the test document flipV attribute is defined for a group shape
-    // This transformation is not applied on child shapes
-    // To make the text direction right at least I added an additional text rotation when parent shape is flipped.
-    sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109223.pptx"), PPTX);
-    uno::Reference< container::XIndexAccess > xGroupShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW);
-    uno::Reference< beans::XPropertySet > xShape(xGroupShape->getByIndex(1), uno::UNO_QUERY);
-
-    // Check the shape text to make sure we test the right shape
-    OUString sText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY)->getString();
-    CPPUNIT_ASSERT_EQUAL(OUString("Tested child shape"), sText);
-
-    // Check the attribute inherited from parent shape
-    bool bAttributeFound = false;
-    uno::Sequence<beans::PropertyValue> aProps;
-    CPPUNIT_ASSERT(xShape->getPropertyValue("CustomShapeGeometry") >>= aProps);
-    for (sal_Int32 i = 0; i < aProps.getLength(); ++i)
-    {
-        const beans::PropertyValue& rProp = aProps[i];
-        if (rProp.Name == "TextPreRotateAngle")
-        {
-            CPPUNIT_ASSERT_EQUAL(sal_Int32(180), rProp.Value.get<sal_Int32>());
-            bAttributeFound = true;
-            break;
-        }
-    }
-
-    CPPUNIT_ASSERT_EQUAL(true, bAttributeFound);
-    xDocShRef->DoClose();
-}
-
 void SdImportTest::testTdf109187()
 {
     sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf109187.pptx"), PPTX);
@@ -2298,6 +2266,19 @@ void SdImportTest::testTdf108926()
     xDocShRef->DoClose();
 }
 
+void SdImportTest::testTdf100065()
+{
+    sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf100065.pptx"), PPTX);
+    uno::Reference< container::XIndexAccess > xGroupShape(getShapeFromPage(0, 0, xDocShRef), uno::UNO_QUERY_THROW);
+    uno::Reference< beans::XPropertySet > xShape(xGroupShape->getByIndex(1), uno::UNO_QUERY_THROW);
+
+    sal_Int32 nAngle;
+    CPPUNIT_ASSERT(xShape->getPropertyValue("RotateAngle") >>= nAngle);
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(2000), nAngle);
+
+    xDocShRef->DoClose();
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();


More information about the Libreoffice-commits mailing list