tdf#136176 Correct update fObjectRotation in NbcShear
Change-Id: I4a73a720845436d25fc1a02eb615dad47f17f96d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103269
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx
index e500c9b..10abdad 100644
--- a/svx/qa/unit/customshapes.cxx
+++ b/svx/qa/unit/customshapes.cxx
@@ -12,10 +12,14 @@
#include <rtl/ustring.hxx>
#include <editeng/unoprnms.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <svx/EnhancedCustomShape2d.hxx>
#include <svx/svdoashp.hxx>
#include <svx/svdopath.hxx>
#include <svx/unoapi.hxx>
#include <unotools/mediadescriptor.hxx>
#include <unotools/tempfile.hxx>
#include <cppunit/TestAssert.h>
@@ -24,6 +28,7 @@
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/frame/XStorable.hpp>
using namespace ::com::sun::star;
@@ -749,6 +754,58 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf122323_largeSwingAngle)
const basegfx::B2DPoint aEnd(aPolygon.getB2DPoint(aPolygon.count() - 2));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Start <> End", aStart, aEnd);
}
CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf136176)
{
// Error was, that fObjectRotation was not correctly updated after shearing.
// The problem becomes visible after save and reload.
OUString sURL = m_directories.getURLFromSrc(sDataDirectory) + "tdf136176_rot30_flip.odg";
mxComponent = loadFromDesktop(sURL, "com.sun.star.comp.drawing.DrawingDocument");
CPPUNIT_ASSERT_MESSAGE("Could not load document", mxComponent.is());
for (sal_uInt16 i = 0; i < 3; i++)
{
// get shape
uno::Reference<drawing::XShape> xShape(getShape(i));
SdrObjCustomShape& rSdrObjCustomShape(
static_cast<SdrObjCustomShape&>(*GetSdrObjectFromXShape(xShape)));
// apply shearing 20deg
const Point aCenter = rSdrObjCustomShape.GetSnapRect().Center();
rSdrObjCustomShape.Shear(aCenter, 2000, tan(basegfx::deg2rad(20.0)), false);
}
// Save and reload
uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
utl::TempFile aTempFile;
utl::MediaDescriptor aMediaDescriptor;
aMediaDescriptor["FilterName"] <<= OUString("draw8");
xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
mxComponent->dispose();
mxComponent = loadFromDesktop(aTempFile.GetURL());
// Expected values of point 4 of the shape polygon
const OString sTestCase[] = { "FlipH", "FlipV", "FlipHV" };
const double fX[] = { 14981.0, 3849.0, 15214.0 };
const double fY[] = { 9366.0, 16464.0, 23463.0 };
// Verify correct positions
for (sal_uInt16 i = 0; i < 3; i++)
{
// Get shape
const uno::Reference<drawing::XShape> xShape(getShape(i));
const SdrObjCustomShape& rSdrObjCustomShape(
static_cast<SdrObjCustomShape&>(*GetSdrObjectFromXShape(xShape)));
// Create polygon from shape and examine point 4 of the polygon
const basegfx::B2DPolyPolygon aLineGeometry = rSdrObjCustomShape.GetLineGeometry(false);
const basegfx::B2DPoint aPoint(aLineGeometry.getB2DPolygon(0).getB2DPoint(4));
// Allow some tolerance for rounding errors
if (fabs(aPoint.getX() - fX[i]) > 2.0 || fabs(aPoint.getY() - fY[i]) > 2.0)
{
CPPUNIT_ASSERT_EQUAL_MESSAGE(sTestCase[i].getStr(), aPoint,
basegfx::B2DPoint(fX[i], fY[i]));
}
}
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/qa/unit/data/tdf136176_rot30_flip.odg b/svx/qa/unit/data/tdf136176_rot30_flip.odg
new file mode 100644
index 0000000..75707a0
--- /dev/null
+++ b/svx/qa/unit/data/tdf136176_rot30_flip.odg
Binary files differ
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 662ab4a0..3e7391d 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -1649,22 +1649,29 @@ void SdrObjCustomShape::NbcShear( const Point& rRef, long nAngle, double tn, boo
// updating fObjectRotation
long nTextObjRotation = aGeo.nRotationAngle;
double fAngle = nTextObjRotation;
fAngle /= 100.0;
bool bSingleFlip = (IsMirroredX()!= IsMirroredY());
fObjectRotation = fmod( bSingleFlip ? -fAngle : fAngle, 360.0 );
if ( fObjectRotation < 0 )
if (IsMirroredX())
{
fObjectRotation = 360.0 + fObjectRotation;
if (IsMirroredY())
fObjectRotation = fAngle - 180.0;
else
fObjectRotation = -fAngle;
}
else
{
if (IsMirroredY())
fObjectRotation = 180.0 - fAngle;
else
fObjectRotation = fAngle;
}
while (fObjectRotation < 0)
fObjectRotation += 360.0;
while (fObjectRotation >= 360.0)
fObjectRotation -= 360.0;
InvalidateRenderGeometry();
}
SdrGluePoint SdrObjCustomShape::GetVertexGluePoint(sal_uInt16 nPosNum) const
{
sal_Int32 nWdt = ImpGetLineWdt(); // #i25616#