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 );