sc/qa/unit/data/ods/LargeAnchorOffset.ods |binary sc/qa/unit/scshapetest.cxx | 34 ++++++++++++++++++++++++++++++ sc/source/filter/xml/xmlexprt.cxx | 8 ++----- 3 files changed, 37 insertions(+), 5 deletions(-)
New commits: commit 7d5dcf5f547e29d61e788b88f7a3f7b4feafb6b2 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Wed Jun 22 16:22:50 2022 +0300 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Wed Jun 22 19:28:19 2022 +0200 Fix shape rectangle calculation At specific screen resolutions, caused failed CppunitTest_sc_shapetest: C:/lo/src/core/sc/qa/unit/scshapetest.cxx(169) : error : Assertion Test name: sc_apitest::ScShapeTest::testTdf137576_LogicRectInDefaultMeasureline assertion failed - Expression: std::abs(rExpected.Y() - rActual.Y()) <= nTolerance - after reload Y expected 9731 actual 10287 Tolerance 1 which manifested the actual wrong position of shape written into ODF. Commit cd966aac6ecd8ce606ac3f2ccd602e467114ba3f Author Regina Henschel <rb.hensc...@t-online.de> Date Fri Dec 25 19:27:51 2020 +0100 tdf#137033 improve save of cell anchored shapes had corrected the calculation of anchor point, but the overlook was that in some cases of non-transformed shapes, rMyCell.maCellAddress may differ from pObjData->maStart. Since aSnapStartAddress could be not set to pObjData->maStart for such shapes, the wrong cell range could be calculated for resized-with-cell objects. Fix this by using pObjData->maStart whenever there is pObjData. If it turns out that in some cases, rMyCell.maCellAddress is needed in calculations before the 'if (rShape.bResizeWithCell && pObjData)', aSnapStartAddress should be assigned to pObjData->maStart after the check. Change-Id: I7e0dc834c2ffb147430fb5b2cb8bdb4dca201b3b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136285 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/sc/qa/unit/data/ods/LargeAnchorOffset.ods b/sc/qa/unit/data/ods/LargeAnchorOffset.ods new file mode 100644 index 000000000000..c7e44527e235 Binary files /dev/null and b/sc/qa/unit/data/ods/LargeAnchorOffset.ods differ diff --git a/sc/qa/unit/scshapetest.cxx b/sc/qa/unit/scshapetest.cxx index 761db2da687c..dc47be21b0d3 100644 --- a/sc/qa/unit/scshapetest.cxx +++ b/sc/qa/unit/scshapetest.cxx @@ -71,6 +71,7 @@ public: void testCustomShapeCellAnchoredRotatedShape(); void testTdf144242_Line_noSwapWH(); void testTdf144242_OpenBezier_noSwapWH(); + void testLargeAnchorOffset(); CPPUNIT_TEST_SUITE(ScShapeTest); CPPUNIT_TEST(testTdf143619_validation_circle_pos); @@ -100,6 +101,7 @@ public: CPPUNIT_TEST(testCustomShapeCellAnchoredRotatedShape); CPPUNIT_TEST(testTdf144242_Line_noSwapWH); CPPUNIT_TEST(testTdf144242_OpenBezier_noSwapWH); + CPPUNIT_TEST(testLargeAnchorOffset); CPPUNIT_TEST_SUITE_END(); }; @@ -1234,6 +1236,38 @@ void ScShapeTest::testCustomShapeCellAnchoredRotatedShape() pDocSh->DoClose(); } +void ScShapeTest::testLargeAnchorOffset() +{ + // The example doc contains a resize-with-cell-anchored measure line + // with a large vertical offset that shifts the start point onto the + // next cell below. + OUString aFileURL; + createFileURL(u"LargeAnchorOffset.ods", aFileURL); + uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL); + + ScDocShell* pDocSh = lcl_getScDocShellWithAssert(xComponent); + SdrObject* pObj = lcl_getSdrObjectWithAssert(pDocSh->GetDocument(), 0); + + const Point aOldPos = pObj->GetRelativePos(); + // Just to check that it imports correctly + lcl_AssertPointEqualWithTolerance("before reload", { 9504, 9089 }, aOldPos, 1); + + saveAndReload(xComponent, "calc8"); + + pDocSh = lcl_getScDocShellWithAssert(xComponent); + pObj = lcl_getSdrObjectWithAssert(pDocSh->GetDocument(), 0); + + // Without the fix, this would fail: + // Test name: sc_apitest::ScShapeTest::testLargeAnchorOffset + // assertion failed + // - Expression: std::abs(rExpected.Y() - rActual.Y()) <= nTolerance + // - after reload Y expected 9089 actual 9643 Tolerance 1 + const Point aNewPos = pObj->GetRelativePos(); + lcl_AssertPointEqualWithTolerance("after reload", aOldPos, aNewPos, 1); + + pDocSh->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScShapeTest); } diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 57c041f7f5ee..8a781127035a 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -3481,14 +3481,12 @@ void ScXMLExport::WriteShapes(const ScMyCell& rMyCell) // end cell address of snap rect. In case of a transformed shape, it is not in rMyCell. ScAddress aSnapStartAddress = rMyCell.maCellAddress; ScDrawObjData* pObjData = nullptr; - bool bIsShapeTransformed = false; if (pObj) { pObjData = ScDrawLayer::GetObjData(pObj); - bIsShapeTransformed = pObj->GetRotateAngle() != 0_deg100 || pObj->GetShearAngle() != 0_deg100; + if (pObjData) + aSnapStartAddress = pObjData->maStart; } - if (bIsShapeTransformed && pObjData) - aSnapStartAddress = pObjData->maStart; // In case rows or columns are hidden above or before the snap rect, move the shape to the // position it would have, if these rows and columns are visible. @@ -3509,7 +3507,7 @@ void ScXMLExport::WriteShapes(const ScMyCell& rMyCell) // tdf#137033 In case the shape is anchored "To Cell (resize with cell)" hiding rows or // columns inside the snap rect has not only changed size of the shape but rotate and shear // angle too. We resize the shape to full size. That will recover the original angles too. - if (rShape.bResizeWithCell && pObjData && pObj) + if (rShape.bResizeWithCell && pObjData) // implies pObj & aSnapStartAddress = pObjData->maStart { // Get original size from anchor const Point aSnapStartOffset = pObjData->maStartOffset;