tdf#105875 DOCX VML shape import: fix missing rotation
Also to avoid bad resizing of the rotated
shape, remove obsolete(?) code part from
commit 0423a6741fc08a35b123556f9b10219d090ee42a
(Import bezier curves from .docx.).
Co-authored-by: Szabolcs Toth
Change-Id: I77266ba65e558cf9e6dd0e1c37fad85abd038819
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103693
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
(cherry picked from commit 3b6de95a0d59cf5942af5ecf4a402c224b76f8a3)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103976
Tested-by: Jenkins
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index d52e8e9..a7a0c46 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -1108,6 +1108,21 @@ Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes
aPropSet.setProperty( PROP_PolyPolygonBezier, aBezierCoords );
}
// tdf#105875 handle rotation
// Note: must rotate before flip!
if (!maTypeModel.maRotation.isEmpty())
{
if (SdrObject* pShape = GetSdrObjectFromXShape(xShape))
{
// -1 is required because the direction of MSO rotation is the opposite of ours
// 100 is required because in this part of the code the angle is in a hundredth of
// degrees.
auto nAngle = -1 * 100.0 * maTypeModel.maRotation.toDouble();
double nHRad = nAngle * F_PI18000;
pShape->NbcRotate(pShape->GetSnapRect().Center(), nAngle, sin(nHRad), cos(nHRad));
}
}
// Handle horizontal and vertical flip.
if (!maTypeModel.maFlip.isEmpty())
{
@@ -1130,17 +1145,6 @@ Reference< XShape > BezierShape::implConvertAndInsert( const Reference< XShapes
}
}
// Hacky way of ensuring the shape is correctly sized/positioned
try
{
// E.g. SwXFrame::setPosition() unconditionally throws
xShape->setSize( awt::Size( rShapeRect.Width, rShapeRect.Height ) );
xShape->setPosition( awt::Point( rShapeRect.X, rShapeRect.Y ) );
}
catch (const ::css::uno::Exception&)
{
// TODO: try some other way to ensure size/position
}
return xShape;
}
diff --git a/sw/qa/extras/ooxmlexport/data/tdf105875_VmlShapeRotationWithFlip.docx b/sw/qa/extras/ooxmlexport/data/tdf105875_VmlShapeRotationWithFlip.docx
new file mode 100644
index 0000000..e6512e0
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf105875_VmlShapeRotationWithFlip.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
index 8921cc0..f209ed4 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport10.cxx
@@ -1325,6 +1325,40 @@ DECLARE_OOXMLEXPORT_TEST(testTdf77236_MissingSolidFill, "tdf77236_MissingSolidFi
assertXPath(pXmlDoc, "//mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:solidFill", 1);
}
DECLARE_OOXMLEXPORT_TEST(testTdf105875_VmlShapeRotationWithFlip, "tdf105875_VmlShapeRotationWithFlip.docx")
{
// tdf#105875: check whether the rotation of the VML bezier shape is ok (with flip too)
// TODO: fix export too
if (mbExported)
return;
{
uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xPropertySet->getPropertyValue("RotateAngle").get<sal_Int32>());
}
{
uno::Reference<beans::XPropertySet> xPropertySet(getShape(2), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(220 * 100), xPropertySet->getPropertyValue("RotateAngle").get<sal_Int32>(), 1);
}
{
uno::Reference<beans::XPropertySet> xPropertySet(getShape(3), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(320 * 100), xPropertySet->getPropertyValue("RotateAngle").get<sal_Int32>(), 1);
}
{
uno::Reference<beans::XPropertySet> xPropertySet(getShape(4), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(140 * 100), xPropertySet->getPropertyValue("RotateAngle").get<sal_Int32>(), 1);
}
{
uno::Reference<beans::XPropertySet> xPropertySet(getShape(5), uno::UNO_QUERY_THROW);
CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(40 * 100), xPropertySet->getPropertyValue("RotateAngle").get<sal_Int32>(), 1);
}
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index fb71f67..f932e973 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -704,7 +704,7 @@ DECLARE_OOXMLIMPORT_TEST(testTdf105127, "tdf105127.docx")
// ForceMetricTo100th_mm -> the old results were in twips due to the
// object residing in Writer. The UNO API by definition is in 100thmm,
// thus I will correct the value here.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5744), aPolyPolygon.Coordinates[0][0].Y); // was: 3257
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5719), aPolyPolygon.Coordinates[0][0].Y); // was: 3257
}
DECLARE_OOXMLIMPORT_TEST(testTdf105143, "tdf105143.docx")
@@ -712,7 +712,7 @@ DECLARE_OOXMLIMPORT_TEST(testTdf105143, "tdf105143.docx")
OUString aTop = parseDump("/root/page/body/txt/anchored/SwAnchoredDrawObject/bounds", "top");
// This was 6272, i.e. the shape was moved up (incorrect position) to be
// inside the page rectangle.
CPPUNIT_ASSERT_EQUAL(OUString("6674"), aTop);
CPPUNIT_ASSERT_EQUAL(OUString("6731"), aTop);
}
DECLARE_OOXMLIMPORT_TEST(testTdf105975, "105975.docx")