From 207d202ed2f1f44e5b62157b5a92ee5e8cc2c3e5 Mon Sep 17 00:00:00 2001 From: Dhiraj Holden Date: Sat, 1 Jan 2022 20:14:33 -0500 Subject: tdf#130076 Fixed flip not working properly from file Added code to check whether the angles need to be changed when the section is flipped. Change-Id: I9cc3e16db74c6e9616385bc39849e4c73686b56c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127853 Tested-by: Jenkins Reviewed-by: Regina Henschel --- svx/qa/unit/classicshapes.cxx | 42 ++++++++++++++++++++- svx/qa/unit/data/tdf130076_FlipOnSectorSection.odg | Bin 0 -> 13736 bytes xmloff/source/draw/ximpshap.cxx | 25 +++++++++++- 3 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 svx/qa/unit/data/tdf130076_FlipOnSectorSection.odg diff --git a/svx/qa/unit/classicshapes.cxx b/svx/qa/unit/classicshapes.cxx index 8d8ed8bd74e4..d9e0fc18c7c1 100644 --- a/svx/qa/unit/classicshapes.cxx +++ b/svx/qa/unit/classicshapes.cxx @@ -181,6 +181,46 @@ CPPUNIT_TEST_FIXTURE(ClassicshapesTest, testTdf98583ShearHorizontal) CPPUNIT_ASSERT_EQUAL(OUString(), sErrors); } -} +CPPUNIT_TEST_FIXTURE(ClassicshapesTest, testTdf130076Flip) +{ + // The document contains sections of a circle, one of which is scaled + // (1, -1), one of which is scaled (-1,1), one of which is transformed + // by a matrix equivalent to a vertical flip, and another which is + // transformed by a matrix equivalent to a horizontal flip. Error was + // that the transformation was made before the CircleKind was set, + // resulting in the flip being performed incorrectly. + const OUString sURL(m_directories.getURLFromSrc(sDataDirectory) + + "tdf130076_FlipOnSectorSection.odg"); + mxComponent = loadFromDesktop(sURL, "com.sun.star.comp.drawing.DrawingDocument"); + + OUString sErrors; // sErrors collects the errors and should be empty in case all is OK. + + for (sal_uInt8 nPageIndex = 0; nPageIndex < 2; ++nPageIndex) + { + sal_Int32 angle1, angle2; + const sal_Int32 goodAngle1 = 26000; + const sal_Int32 goodAngle2 = 26000; + uno::Reference xShape(getShape(1, nPageIndex)); + uno::Reference xShapeProps(xShape, uno::UNO_QUERY); + uno::Reference xShape2(getShape(2, nPageIndex)); + uno::Reference xShapeProps2(xShape2, uno::UNO_QUERY); + xShapeProps->getPropertyValue("CircleStartAngle") >>= angle1; + xShapeProps2->getPropertyValue("CircleStartAngle") >>= angle2; + if (angle1 != goodAngle1) + { + sErrors += "page " + OUString::number(nPageIndex) + + " expected vertical flip starting angle " + OUString::number(goodAngle1) + + " actual " + OUString::number(angle1) + "\n"; + } + if (angle2 != goodAngle2) + { + sErrors += "page " + OUString::number(nPageIndex) + + " expected horizontal flip starting angle " + OUString::number(goodAngle2) + + " actual " + OUString::number(angle2) + "\n"; + } + } + CPPUNIT_ASSERT_EQUAL(OUString(), sErrors); +} +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/qa/unit/data/tdf130076_FlipOnSectorSection.odg b/svx/qa/unit/data/tdf130076_FlipOnSectorSection.odg new file mode 100644 index 000000000000..058e7e0443f9 Binary files /dev/null and b/svx/qa/unit/data/tdf130076_FlipOnSectorSection.odg differ diff --git a/xmloff/source/draw/ximpshap.cxx b/xmloff/source/draw/ximpshap.cxx index 4d2dec38a3c8..a19a6c19d936 100644 --- a/xmloff/source/draw/ximpshap.cxx +++ b/xmloff/source/draw/ximpshap.cxx @@ -1172,7 +1172,6 @@ void SdXMLEllipseShapeContext::startFastElement (sal_Int32 nElement, maPosition.X = mnCX - mnRX; maPosition.Y = mnCY - mnRY; } - // set pos, size, shear and rotate SetTransformation(); @@ -1181,6 +1180,30 @@ void SdXMLEllipseShapeContext::startFastElement (sal_Int32 nElement, uno::Reference< beans::XPropertySet > xPropSet( mxShape, uno::UNO_QUERY ); if( xPropSet.is() ) { + // calculate the correct start and end angle + sal_Int32 mnOldStartAngle = mnStartAngle; + sal_Int32 mnOldEndAngle = mnEndAngle; + basegfx::B2DTuple aScale; + basegfx::B2DTuple aTranslate; + double fRotate; + double fShearX; + maUsedTransformation.decompose(aScale, aTranslate, fRotate, fShearX); + if (aScale.getX() < 0 || aScale.getY() < 0) + { + // The angle for a horizontal flip is the same as the angle for a + // vertical flip because a vertical flip is treated as a horizontal + // flip plus a rotation. + + // To perform the flip, the start and end angle are switched and we + // use the fact performing a horizontal flip on a shape will change + // the angle that a radius makes with the origin to 180 degrees + // minus that angle (we use 54000 hundredths of a degree to get the + // modulus operation to give a value between 0 and 36000). + + mnStartAngle = (54000 - mnOldEndAngle) % 36000; + mnEndAngle = (54000 - mnOldStartAngle) % 36000; + } + xPropSet->setPropertyValue("CircleKind", Any( meKind) ); xPropSet->setPropertyValue("CircleStartAngle", Any(mnStartAngle) ); xPropSet->setPropertyValue("CircleEndAngle", Any(mnEndAngle) ); -- cgit