summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oox/qa/unit/data/camera-rotation-revolution.docxbin0 -> 23748 bytes
-rw-r--r--oox/qa/unit/drawingml.cxx25
-rw-r--r--oox/source/drawingml/shape.cxx7
-rw-r--r--oox/source/export/drawingml.cxx32
4 files changed, 60 insertions, 4 deletions
diff --git a/oox/qa/unit/data/camera-rotation-revolution.docx b/oox/qa/unit/data/camera-rotation-revolution.docx
new file mode 100644
index 000000000000..74054aa82b3f
--- /dev/null
+++ b/oox/qa/unit/data/camera-rotation-revolution.docx
Binary files differ
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index 7fcee1756a6f..6a0415b257f2 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -265,6 +265,31 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testShapeTextAdjustLeft)
CPPUNIT_ASSERT_EQUAL(drawing::TextHorizontalAdjust_BLOCK, eAdjust);
}
+CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testCameraRotationRevolution)
+{
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "camera-rotation-revolution.docx";
+ 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: 8000
+ // - Actual : 0
+ // so the camera rotation would not have been factored into how the shape is displayed
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(8000), nRotateAngle0);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(27000), nRotateAngle1);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index c9ade16f7a1d..95b608eadcc6 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1461,11 +1461,14 @@ Reference< XShape > const & Shape::createAndInsert(
else if( getTextBody() )
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 )
+ if ( !bUseRotationTransform && (mnRotation != 0 || nCameraRotation != 0) )
{
// use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx)
- aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle36000( mnRotation / -600 ) ) ) );
+ aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle36000( (mnRotation - nCameraRotation) / -600 ) ) ) );
aPropertySet.setAnyProperty( PROP_HoriOrientPosition, makeAny( maPosition.X ) );
aPropertySet.setAnyProperty( PROP_VertOrientPosition, makeAny( maPosition.Y ) );
}
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 4a9ac9f69014..c19b030ad642 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1708,7 +1708,8 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa
{
SAL_INFO("oox.shape", "write shape transformation");
- sal_Int32 nRotation=0;
+ sal_Int32 nRotation = 0;
+ sal_Int32 nCameraRotation = 0;
awt::Point aPos = rXShape->getPosition();
awt::Size aSize = rXShape->getSize();
@@ -1745,6 +1746,33 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa
uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
if (xPropertySetInfo->hasPropertyByName("RotateAngle"))
xPropertySet->getPropertyValue("RotateAngle") >>= nRotation;
+ // tdf#133037: restore original rotate angle before output
+ if (xPropertySetInfo->hasPropertyByName(UNO_NAME_MISC_OBJ_INTEROPGRABBAG))
+ {
+ uno::Sequence<beans::PropertyValue> aGrabBagProps;
+ xPropertySet->getPropertyValue(UNO_NAME_MISC_OBJ_INTEROPGRABBAG) >>= aGrabBagProps;
+ auto p3DEffectProps = std::find_if(std::cbegin(aGrabBagProps), std::cend(aGrabBagProps),
+ [](const PropertyValue& rProp) { return rProp.Name == "3DEffectProperties"; });
+ if (p3DEffectProps != std::cend(aGrabBagProps))
+ {
+ uno::Sequence<beans::PropertyValue> a3DEffectProps;
+ p3DEffectProps->Value >>= a3DEffectProps;
+ auto pCameraProps = std::find_if(std::cbegin(a3DEffectProps), std::cend(a3DEffectProps),
+ [](const PropertyValue& rProp) { return rProp.Name == "Camera"; });
+ if (pCameraProps != std::cend(a3DEffectProps))
+ {
+ uno::Sequence<beans::PropertyValue> aCameraProps;
+ pCameraProps->Value >>= aCameraProps;
+ auto pZRotationProp = std::find_if(std::cbegin(aCameraProps), std::cend(aCameraProps),
+ [](const PropertyValue& rProp) { return rProp.Name == "rotRev"; });
+ if (pZRotationProp != std::cend(aCameraProps))
+ {
+ pZRotationProp->Value >>= nCameraRotation;
+ nCameraRotation = NormAngle36000(nCameraRotation / -600);
+ }
+ }
+ }
+ }
}
// OOXML flips shapes before rotating them.
@@ -1752,7 +1780,7 @@ void DrawingML::WriteShapeTransformation( const Reference< XShape >& rXShape, sa
nRotation = nRotation * -1 + 36000;
WriteTransformation(tools::Rectangle(Point(aPos.X, aPos.Y), Size(aSize.Width, aSize.Height)), nXmlNamespace,
- bFlipHWrite, bFlipVWrite, ExportRotateClockwisify(nRotation), IsGroupShape( rXShape ));
+ bFlipHWrite, bFlipVWrite, ExportRotateClockwisify(nRotation + nCameraRotation), IsGroupShape( rXShape ));
}
void DrawingML::WriteRunProperties( const Reference< XPropertySet >& rRun, bool bIsField, sal_Int32 nElement,