include/oox/export/drawingml.hxx                        |    6 ++-
 oox/qa/unit/data/camera-rotation-revolution-nonwps.pptx |binary
 oox/qa/unit/drawingml.cxx                               |   26 ++++++++++++++
 oox/source/drawingml/shape.cxx                          |    7 +---
 oox/source/export/drawingml.cxx                         |   28 +++-------------
 oox/source/export/shapes.cxx                            |    4 +-
 6 files changed, 42 insertions(+), 29 deletions(-)

New commits:
commit db62747b328486c559082254401aa40516e4b98e
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Mon Jan 3 05:45:17 2022 +0300
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jan 12 09:13:33 2022 +0100

    tdf#146534 pptx import: make Z rotation work with rotation transform
    
    Expands previous idea from a9c5c0d814a266096483572b84c72875ef8efd77
    (tdf#133037 OOXML shape import: camera rotation along Z)
    and uses it also for shapes that have a true bUseRotationTransform flag
    
    Also fixes same Z rotation exporting twice from InteropGrabBag to
    both spPr and textBody causing text overrotating on roundtrip.
    
    Dropped the export unit test while cherry-picking to cp-6.4
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127880
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry-picked from commit 8bdd134bef3baca2ebd878163af4e55e5f898efe)
    
    Change-Id: If0f192af029ca86b932a63613f961be1f5003c5b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128275
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index fa309108c055..f67af98f9369 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -297,7 +297,11 @@ public:
     void WriteShapeStyle( const css::uno::Reference< css::beans::XPropertySet 
>& rXPropSet );
     void WriteShapeEffects( const css::uno::Reference< 
css::beans::XPropertySet >& rXPropSet );
     void WriteShapeEffect( const OUString& sName, const css::uno::Sequence< 
css::beans::PropertyValue >& aEffectProps );
-    void WriteShape3DEffects( const css::uno::Reference< 
css::beans::XPropertySet >& rXPropSet );
+    /** Populates scene3d tag
+        @param rXPropSet Prop set
+        @param bIsText True if the 3D effects are for a text body, false if it 
is for a shape
+     */
+    void Write3DEffects(const css::uno::Reference<css::beans::XPropertySet>& 
rXPropSet, bool bIsText);
     void WriteArtisticEffect( const css::uno::Reference< 
css::beans::XPropertySet >& rXPropSet );
     OString WriteWdpPicture( const OUString& rFileId, const 
css::uno::Sequence< sal_Int8 >& rPictureData );
     void WriteDiagram(const css::uno::Reference<css::drawing::XShape>& 
rXShape, int nDiagramId);
diff --git a/oox/qa/unit/data/camera-rotation-revolution-nonwps.pptx 
b/oox/qa/unit/data/camera-rotation-revolution-nonwps.pptx
new file mode 100755
index 000000000000..db26dc032caa
Binary files /dev/null and 
b/oox/qa/unit/data/camera-rotation-revolution-nonwps.pptx differ
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index a5be52f66c9e..66c95e366460 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -299,6 +299,32 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, 
testCameraRotationRevolution)
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(27000), nRotateAngle1);
 }
 
+CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, 
testTdf146534_CameraRotationRevolutionNonWpsShapes)
+{
+    OUString aURL
+        = m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"camera-rotation-revolution-nonwps.pptx";
+    load(aURL);
+
+    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> xShape0(xDrawPage->getByIndex(0), 
uno::UNO_QUERY);
+    uno::Reference<container::XNamed> xShape1(xDrawPage->getByIndex(1), 
uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xShapeProps0(xShape0, uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xShapeProps1(xShape1, uno::UNO_QUERY);
+    sal_Int32 nRotateAngle0;
+    sal_Int32 nRotateAngle1;
+    xShapeProps0->getPropertyValue("RotateAngle") >>= nRotateAngle0;
+    xShapeProps1->getPropertyValue("RotateAngle") >>= nRotateAngle1;
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 9000
+    // - Actual  : 0
+    // so the camera rotation would not have been factored into how the shape 
is displayed
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(9000), nRotateAngle0);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(30500), nRotateAngle1);
+}
+
 CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTableShadow)
 {
     auto verify = [](const uno::Reference<lang::XComponent>& xComponent) {
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index 803e130b349a..fbf8c9c02eec 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -763,7 +763,8 @@ Reference< XShape > const & Shape::createAndInsert(
     }
 
     bool bNoTranslation = !aParentTransformation.isIdentity();
-    if( mbFlipH || mbFlipV || mnRotation != 0 || bNoTranslation )
+    const sal_Int32 nCameraRotation = 
get3DProperties().maCameraRotation.mnRevolution.get(0);
+    if( mbFlipH || mbFlipV || mnRotation != 0 || nCameraRotation != 0 || 
bNoTranslation )
     {
         // calculate object's center
         basegfx::B2DPoint aCenter(0.5, 0.5);
@@ -799,7 +800,7 @@ Reference< XShape > const & Shape::createAndInsert(
                 }
             }
             // rotate around object's center
-            
aTransformation.rotate(basegfx::deg2rad(static_cast<double>(mnRotation) / 
60000.0));
+            
aTransformation.rotate(basegfx::deg2rad(static_cast<double>(mnRotation - 
nCameraRotation) / 60000.0));
         }
 
         // move object back from center
@@ -1458,8 +1459,6 @@ Reference< XShape > const & Shape::createAndInsert(
             getTextBody()->getTextProperties().pushVertSimulation();
 
         // tdf#133037: a bit hackish: force Shape to rotate in the opposite 
direction the camera would rotate
-        const sal_Int32 nCameraRotation = 
get3DProperties().maCameraRotation.mnRevolution.get(0);
-
         PropertySet aPropertySet(mxShape);
         if ( !bUseRotationTransform && (mnRotation != 0 || nCameraRotation != 
0) )
         {
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index dacfe516585c..f5ddabb12939 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -3098,7 +3098,7 @@ void DrawingML::WriteText( const Reference< XInterface >& 
rXIface, const OUStrin
             }
         }
 
-        WriteShape3DEffects( rXPropSet );
+        Write3DEffects( rXPropSet, /*bIsText=*/true );
 
         mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), 
XML_bodyPr);
     }
@@ -4036,7 +4036,7 @@ void DrawingML::WriteShapeEffects( const Reference< 
XPropertySet >& rXPropSet )
     }
 }
 
-void DrawingML::WriteShape3DEffects( const Reference< XPropertySet >& xPropSet 
)
+void DrawingML::Write3DEffects( const Reference< XPropertySet >& xPropSet, 
bool bIsText )
 {
     // check existence of the grab bag
     if( !GetProperty( xPropSet, "InteropGrabBag" ) )
@@ -4045,8 +4045,10 @@ void DrawingML::WriteShape3DEffects( const Reference< 
XPropertySet >& xPropSet )
     // extract the relevant properties from the grab bag
     Sequence< PropertyValue > aGrabBag, aEffectProps, aLightRigProps, 
aShape3DProps;
     mAny >>= aGrabBag;
-    auto pShapeProp = std::find_if(std::cbegin(aGrabBag), std::cend(aGrabBag),
-        [](const PropertyValue& rProp) { return rProp.Name == 
"3DEffectProperties"; });
+
+    auto pShapeProp = std::find_if( std::cbegin(aGrabBag), std::cend(aGrabBag),
+        [bIsText](const PropertyValue& rProp)
+        { return rProp.Name == (bIsText ? u"Text3DEffectProperties" : 
u"3DEffectProperties"); });
     if (pShapeProp != std::cend(aGrabBag))
     {
         Sequence< PropertyValue > a3DEffectProps;
@@ -4062,24 +4064,6 @@ void DrawingML::WriteShape3DEffects( const Reference< 
XPropertySet >& xPropSet )
         }
     }
 
-    auto pTextProp = std::find_if(std::cbegin(aGrabBag), std::cend(aGrabBag),
-        [](const PropertyValue& rProp) { return rProp.Name == 
"Text3DEffectProperties"; });
-
-    if (pTextProp != std::cend(aGrabBag))
-    {
-        Sequence< PropertyValue > a3DEffectProps;
-        pTextProp->Value >>= a3DEffectProps;
-        for( const auto& r3DEffectProp : std::as_const(a3DEffectProps) )
-        {
-            if( r3DEffectProp.Name == "Camera" )
-                r3DEffectProp.Value >>= aEffectProps;
-            else if( r3DEffectProp.Name == "LightRig" )
-                r3DEffectProp.Value >>= aLightRigProps;
-            else if( r3DEffectProp.Name == "Shape3D" )
-                r3DEffectProp.Value >>= aShape3DProps;
-        }
-    }
-
     if( !aEffectProps.hasElements() && !aLightRigProps.hasElements() && 
!aShape3DProps.hasElements() )
         return;
 
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index 1eb48b0efc5c..ef9fdfd12282 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -1059,7 +1059,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const 
Reference< XShape >& xShape )
                 bHas3DEffectinShape = true;
 
         if( bHas3DEffectinShape)
-            WriteShape3DEffects( rXPropSet );
+            Write3DEffects( rXPropSet, /*bIsText=*/false );
     }
 
     pFS->endElementNS( mnXmlNamespace, XML_spPr );
@@ -1313,7 +1313,7 @@ void ShapeExport::WriteGraphicObjectShapePart( const 
Reference< XShape >& xShape
     WriteOutline( xShapeProps );
 
     WriteShapeEffects( xShapeProps );
-    WriteShape3DEffects( xShapeProps );
+    Write3DEffects( xShapeProps, /*bIsText=*/false );
 
     pFS->endElementNS( mnXmlNamespace, XML_spPr );
 

Reply via email to