tdf#144242 no width-height swap for line and pathline
MS Office swaps width and height for rotation angle ranges 45..135 and
225..315. Line and Pathline objects incorporate the rotation into their
points, so have no rotation. Line and open Pathline objects nevertheless
report an rotation angle. That one is used to align the text direction
to the line. But because of this reported angle, width and height were
swapped. The patch excludes these objects explicitly.
The case differentiation for the rotation range had forgotten to
normalize the angle. Therefore, in a reopened spreadsheet, the line was
accidentally exported correctly without width-height swap, because in
this case the rotation angle is negative.
Change-Id: I5f698d1cc734e17bcb02ff77db5224a228392e06
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121661
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
diff --git a/sc/qa/unit/scshapetest.cxx b/sc/qa/unit/scshapetest.cxx
index e14ffeb..187bf08 100644
--- a/sc/qa/unit/scshapetest.cxx
+++ b/sc/qa/unit/scshapetest.cxx
@@ -71,6 +71,8 @@
void testTdf115655_HideDetail();
void testFitToCellSize();
void testCustomShapeCellAnchoredRotatedShape();
void testTdf144242_Line_noSwapWH();
void testTdf144242_OpenBezier_noSwapWH();
CPPUNIT_TEST_SUITE(ScShapeTest);
CPPUNIT_TEST(testTdf143619_validation_circle_pos);
@@ -98,6 +100,8 @@
CPPUNIT_TEST(testTdf115655_HideDetail);
CPPUNIT_TEST(testFitToCellSize);
CPPUNIT_TEST(testCustomShapeCellAnchoredRotatedShape);
CPPUNIT_TEST(testTdf144242_Line_noSwapWH);
CPPUNIT_TEST(testTdf144242_OpenBezier_noSwapWH);
CPPUNIT_TEST_SUITE_END();
};
@@ -206,6 +210,86 @@
return pObj;
}
void ScShapeTest::testTdf144242_OpenBezier_noSwapWH()
{
// Shapes, which have rotation incorporated in their points, got erroneously width-height
// swapped, because they report a rotation. (Rotation was introduced to align text with curve.)
// Create a spreadsheet document with default row height and col width
uno::Reference<lang::XComponent> xComponent
= loadFromDesktop("private:factory/scalc", "com.sun.star.sheet.SpreadsheetDocument");
// Get ScDocShell
ScDocShell* pDocSh = lcl_getScDocShellWithAssert(xComponent);
// Insert default open Bezier curve
ScTabViewShell* pTabViewShell = lcl_getScTabViewShellWithAssert(pDocSh);
SfxRequest aReq(pTabViewShell->GetViewFrame(), SID_DRAW_BEZIER_NOFILL);
aReq.SetModifier(KEY_MOD1); // Ctrl
pTabViewShell->ExecDraw(aReq);
pTabViewShell->SetDrawShell(false);
// Get document and newly created object
ScDocument& rDoc = pDocSh->GetDocument();
SdrObject* pObj = lcl_getSdrObjectWithAssert(rDoc, 0);
// Rotate object by 300deg
pObj->Rotate(pObj->GetSnapRect().Center(), 30000_deg100, sin(toRadians(30000_deg100)),
cos(toRadians(30000_deg100)));
tools::Rectangle aExpectRect(pObj->GetSnapRect());
// Save, reload and compare
saveAndReload(xComponent, "Calc Office Open XML");
pDocSh = lcl_getScDocShellWithAssert(xComponent);
ScDocument& rDoc2 = pDocSh->GetDocument();
pObj = lcl_getSdrObjectWithAssert(rDoc2, 0);
tools::Rectangle aSnapRect(pObj->GetSnapRect());
// Without fix in place width and height were swapped
lcl_AssertRectEqualWithTolerance("Reload: wrong pos and size", aExpectRect, aSnapRect, 30);
pDocSh->DoClose();
}
void ScShapeTest::testTdf144242_Line_noSwapWH()
{
// Shapes, which have rotation incorporated in their points, got erroneously width-height
// swapped, because they report a rotation. (Rotation was introduced to align text with line.)
// Create a spreadsheet document with default row height and col width
uno::Reference<lang::XComponent> xComponent
= loadFromDesktop("private:factory/scalc", "com.sun.star.sheet.SpreadsheetDocument");
// Get ScDocShell
ScDocShell* pDocSh = lcl_getScDocShellWithAssert(xComponent);
// Insert default line
ScTabViewShell* pTabViewShell = lcl_getScTabViewShellWithAssert(pDocSh);
SfxRequest aReq(pTabViewShell->GetViewFrame(), SID_DRAW_LINE);
aReq.SetModifier(KEY_MOD1); // Ctrl
pTabViewShell->ExecDraw(aReq);
pTabViewShell->SetDrawShell(false);
// Get document and newly created object
ScDocument& rDoc = pDocSh->GetDocument();
SdrObject* pObj = lcl_getSdrObjectWithAssert(rDoc, 0);
// Rotate object by 300deg
pObj->Rotate(pObj->GetSnapRect().Center(), 30000_deg100, sin(toRadians(30000_deg100)),
cos(toRadians(30000_deg100)));
tools::Rectangle aExpectRect(pObj->GetSnapRect());
// Save, reload and compare
saveAndReload(xComponent, "Calc Office Open XML");
pDocSh = lcl_getScDocShellWithAssert(xComponent);
ScDocument& rDoc2 = pDocSh->GetDocument();
pObj = lcl_getSdrObjectWithAssert(rDoc2, 0);
tools::Rectangle aSnapRect(pObj->GetSnapRect());
// Without fix in place width and height were swapped
lcl_AssertRectEqualWithTolerance("Reload: wrong pos and size", aExpectRect, aSnapRect, 30);
pDocSh->DoClose();
}
void ScShapeTest::testTdf143619_validation_circle_pos()
{
// Load a document, which has validation circle around cell E6.
diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx
index 903d5b5..3d8f1e5 100644
--- a/sc/source/filter/xcl97/xcl97rec.cxx
+++ b/sc/source/filter/xcl97/xcl97rec.cxx
@@ -1103,10 +1103,14 @@
awt::Size aSize = rShape->getSize();
// There are a few cases where we must adjust these values
// Do not adjust objects, which have rotation incorporated into their points
// but report a rotation angle nevertheless.
SdrObject* pObj = SdrObject::getSdrObjectFromXShape(rShape);
if (pObj)
if (pObj && pObj->GetObjIdentifier() != OBJ_LINE && pObj->GetObjIdentifier() != OBJ_PLIN
&& pObj->GetObjIdentifier() != OBJ_PATHLINE && pObj->GetObjIdentifier() != OBJ_FREELINE
&& pObj->GetObjIdentifier() != OBJ_PATHPLIN)
{
Degree100 nRotation = pObj->GetRotateAngle();
Degree100 nRotation = NormAngle36000(pObj->GetRotateAngle());
if (nRotation)
{
sal_Int16 nHalfWidth = aSize.Width / 2;