From b5adee6643a21d18a5fd865756017f7786fb79f7 Mon Sep 17 00:00:00 2001 From: Szabolcs Toth Date: Mon, 17 Aug 2020 10:55:43 +0200 Subject: tdf#135828 XLSX shape export: fix distortion of rotated shapes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shapes that were rotated at angles {[45, 135) U [225, 315)} need new anchor positions that does an extra 90 degrees rotation. See commit 130e6a3f4493b987a7d0b177cc84d65219b47d13 (tdf#83593 XLSX DrawingML shape import: fix missing rotation) Co-authored-by: Balázs Regényi Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100853 Tested-by: László Németh Reviewed-by: László Németh (cherry picked from commit 5e8875780d665b7ae0fee1a053b5ce78ec513f69) Change-Id: I42a5d203cf3b6f6e725d84dd5f39ac323f4f1ceb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102939 Tested-by: Gabor Kelemen Reviewed-by: Gabor Kelemen --- sc/qa/unit/data/xlsx/tdf135828_Shape_Rect.xlsx | Bin 0 -> 9534 bytes sc/qa/unit/subsequent_export-test.cxx | 20 ++++++++++++++++++++ sc/source/filter/xcl97/xcl97rec.cxx | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 sc/qa/unit/data/xlsx/tdf135828_Shape_Rect.xlsx diff --git a/sc/qa/unit/data/xlsx/tdf135828_Shape_Rect.xlsx b/sc/qa/unit/data/xlsx/tdf135828_Shape_Rect.xlsx new file mode 100644 index 000000000000..c01c81ab6d74 Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf135828_Shape_Rect.xlsx differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 6769aab25f07..9fdf9419f515 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -237,6 +237,7 @@ public: void testTdf134459_HeaderFooterColorXLSX(); void testTdf134817_HeaderFooterTextWith2SectionXLSX(); void testHeaderFontStyleXLSX(); + void testTdf135828_Shape_Rect(); CPPUNIT_TEST_SUITE(ScExportTest); CPPUNIT_TEST(test); @@ -372,6 +373,7 @@ public: CPPUNIT_TEST(testTdf134459_HeaderFooterColorXLSX); CPPUNIT_TEST(testTdf134817_HeaderFooterTextWith2SectionXLSX); CPPUNIT_TEST(testHeaderFontStyleXLSX); + CPPUNIT_TEST(testTdf135828_Shape_Rect); CPPUNIT_TEST_SUITE_END(); @@ -4702,6 +4704,24 @@ void ScExportTest::testHeaderFontStyleXLSX() xShell->DoClose(); } +void ScExportTest::testTdf135828_Shape_Rect() +{ + // tdf#135828 Check that the width and the height of rectangle of the shape + // is correct. + ScDocShellRef xShell = loadDoc("tdf135828_Shape_Rect.", FORMAT_XLSX); + CPPUNIT_ASSERT(xShell.is()); + + ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX); + CPPUNIT_ASSERT(xDocSh.is()); + + std::shared_ptr pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX); + xmlDocPtr pDrawing = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml"); + CPPUNIT_ASSERT(pDrawing); + + assertXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:spPr/a:xfrm/a:ext", "cx", "294480"); // width + assertXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:spPr/a:xfrm/a:ext", "cy", "1990440"); // height +} + CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index 5597b635ecbd..17420fe5c69e 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -1026,6 +1026,25 @@ void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const Reference< XShape >& awt::Point aTopLeft = rShape->getPosition(); awt::Size aSize = rShape->getSize(); + + uno::Reference< beans::XPropertySet > xShapeProperties(rShape, uno::UNO_QUERY_THROW); + uno::Any nRotProp = xShapeProperties->getPropertyValue("RotateAngle"); + sal_Int32 nRot = nRotProp.get(); + + if ((nRot >= 45 * 100 && nRot < 135 * 100) || (nRot >= 225 * 100 && nRot < 315 * 100)) + { + // MSO changes the anchor positions at these angles and that does an extra 90 degrees + // rotation on our shapes, so we output it in such position that MSO + // can draw this shape correctly. + + sal_Int16 nHalfWidth = aSize.Width / 2; + sal_Int16 nHalfHeight = aSize.Height / 2; + aTopLeft.X = aTopLeft.X - nHalfHeight + nHalfWidth; + aTopLeft.Y = aTopLeft.Y - nHalfWidth + nHalfHeight; + + std::swap(aSize.Width, aSize.Height); + } + tools::Rectangle aLocation( aTopLeft.X, aTopLeft.Y, aTopLeft.X + aSize.Width, aTopLeft.Y + aSize.Height ); ScRange aRange = rStrm.GetRoot().GetDoc().GetRange( nTab, aLocation ); tools::Rectangle aRangeRect = rStrm.GetRoot().GetDoc().GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(), -- cgit