From b65de36ecb839ec4d7a8f40f9ffe67956e9bc79d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacobo=20Aragunde=20P=C3=A9rez?= Date: Mon, 14 Apr 2014 17:27:35 +0200 Subject: [PATCH] fdo#75722: fix incorrect import of rotated DML shapes The DML importer used a tranformation matrix to rotate the shape, but I replaced it with the same code that's being used in the VML importer in which the position is correctly set. I've noticed that I cannot use that code in all cases thanks to the existing unit tests; that's why I added the bUseRotationTransform. In case it is set to true the existing transformation matrix rotation is used. Finally I added a unit test for this case. Change-Id: I260c14b42d169def786e15484e4ecb1d8e8584e4 --- oox/source/drawingml/shape.cxx | 15 +++++++++++- sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 29 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 36cbc0c5959d..c1d00f65a42a 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -410,6 +411,9 @@ Reference< XShape > Shape::createAndInsert( } bool bIsCustomShape = ( aServiceName == "com.sun.star.drawing.CustomShape" || aServiceName == "com.sun.star.drawing.ConnectorShape" ); + bool bUseRotationTransform = ( !mbWps || + aServiceName == "com.sun.star.drawing.LineShape" || + aServiceName == "com.sun.star.drawing.GroupShape" ); basegfx::B2DHomMatrix aTransformation; @@ -436,7 +440,7 @@ Reference< XShape > Shape::createAndInsert( aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 ); } - if( mnRotation != 0 ) + if( bUseRotationTransform && mnRotation != 0 ) { // rotate around object's center aTransformation.rotate( F_PI180 * ( (double)mnRotation / 60000.0 ) ); @@ -896,6 +900,15 @@ Reference< XShape > Shape::createAndInsert( else if( getTextBody() ) getTextBody()->getTextProperties().pushVertSimulation(); + if ( !bUseRotationTransform && mnRotation != 0 ) + { + // use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx) + PropertySet aPropertySet( mxShape ); + aPropertySet.setAnyProperty( PROP_RotateAngle, makeAny( sal_Int32( NormAngle360( mnRotation / -600 ) ) ) ); + aPropertySet.setAnyProperty( PROP_HoriOrientPosition, makeAny( maPosition.X ) ); + aPropertySet.setAnyProperty( PROP_VertOrientPosition, makeAny( maPosition.Y ) ); + } + // in some cases, we don't have any text body. if( getTextBody() && ( !bDoNotInsertEmptyTextBody || !mpTextBody->isEmpty() ) ) { diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 103a3db948f4..8961eed81213 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -2019,6 +2019,35 @@ DECLARE_OOXMLIMPORT_TEST(testFdo74401, "fdo74401.docx") CPPUNIT_ASSERT_EQUAL(OUString("com.sun.star.drawing.CustomShape"), xShape->getShapeType()); } +DECLARE_OOXMLIMPORT_TEST(testFdo75722vml, "fdo75722-vml.docx") +{ + uno::Reference xShape = getShape(1); + awt::Point aPos = xShape->getPosition(); + awt::Size aSize = xShape->getSize(); + sal_Int64 nRot = getProperty(xShape, "RotateAngle"); + + CPPUNIT_ASSERT_EQUAL(sal_Int32(3720), aPos.X); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-392), aPos.Y); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5457), aSize.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3447), aSize.Height); + CPPUNIT_ASSERT_EQUAL(sal_Int64(3100), nRot); +} + +DECLARE_OOXMLIMPORT_TEST(testFdo75722dml, "fdo75722-dml.docx") +{ + uno::Reference xShape = getShape(1); + awt::Point aPos = xShape->getPosition(); + awt::Size aSize = xShape->getSize(); + sal_Int64 nRot = getProperty(xShape, "RotateAngle"); + + // a slight difference regarding vml file is tolerated due to rounding errors + CPPUNIT_ASSERT_EQUAL(sal_Int32(3720), aPos.X); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-397), aPos.Y); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5457), aSize.Width); + CPPUNIT_ASSERT_EQUAL(sal_Int32(3447), aSize.Height); + CPPUNIT_ASSERT_EQUAL(sal_Int64(3128), nRot); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT();