diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2022-05-07 14:26:09 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2022-05-07 15:40:49 +0200 |
commit | 323df76698be1e554ba3342f56a812517a25437a (patch) | |
tree | da2e0f65487be16b9cad28943ac1c8ab2c34728e /oox | |
parent | a5af08b3ed160a569d389474dc5d5445dccf3a63 (diff) |
Revert "tdf#147919 PPTX export: fix curved and bent connector shape"
This reverts commit 1f8c6efbfea10997f188962d036f5c7db4c13f8a, as it caues
> warn:legacy.tools:12871:12871:tools/source/generic/poly.cxx:1581: Polygon::[]: nPos >= nPoints
> =================================================================
> ==12871==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000445080 at pc 0x7f6303ec7854 bp 0x7ffd23271600 sp 0x7ffd232715f8
> READ of size 8 at 0x603000445080 thread T0
> #0 0x7f6303ec7853 in Point::X() const /include/tools/gen.hxx:83:51
> #1 0x7f63045baaa1 in oox::drawingml::lcl_GetConnectorAdjustValue(com::sun::star::uno::Reference<com::sun::star::drawing::XShape> const&, tools::Polygon, com::sun::star::drawing::ConnectorType, std::__debug::vector<std::pair<int, int>, std::allocator<std::pair<int, int> > >&) /oox/source/export/shapes.cxx:1556:27
> #2 0x7f63045b731f in oox::drawingml::ShapeExport::WriteConnectorShape(com::sun::star::uno::Reference<com::sun::star::drawing::XShape> const&) /oox/source/export/shapes.cxx:1701:13
> #3 0x7f63045984e7 in oox::drawingml::ShapeExport::WriteShape(com::sun::star::uno::Reference<com::sun::star::drawing::XShape> const&) /oox/source/export/shapes.cxx:1956:5
> #4 0x7f62b399ad3b in oox::core::PowerPointExport::WriteShapeTree(std::shared_ptr<sax_fastparser::FastSerializerHelper> const&, PageType, bool) /sd/source/filter/eppt/pptx-epptooxml.cxx:1658:22
during CppunitTest_sd_export_tests-ooxml3
CPPUNIT_TEST_NAME=SdOOXMLExportTest3::testTdf114848
(<https://ci.libreoffice.org/job/lo_ubsan/2388/consoleFull#-1714579836d893063f-7f3d-4b7e-b56f-4e0f225817cd>)
Change-Id: I7eab9d3ef8e6604a57d3e59a77905edf6ce6e6ac
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133870
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/export/shapes.cxx | 306 |
1 files changed, 28 insertions, 278 deletions
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index de1527ecda0f..3308d5ab4492 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -1411,276 +1411,49 @@ void ShapeExport::WriteGraphicObjectShapePart( const Reference< XShape >& xShape pFS->endElementNS( mnXmlNamespace, XML_pic ); } -static void lcl_Rotate(sal_Int32 nAngle, Point center, awt::Point& pt) -{ - sal_Int16 nCos, nSin; - switch (nAngle) - { - case 90: - nCos = 0; - nSin = 1; - break; - case 180: - nCos = -1; - nSin = 0; - break; - case 270: - nCos = 0; - nSin = -1; - break; - default: - return; - } - sal_Int32 x = pt.X - center.X(); - sal_Int32 y = pt.Y - center.Y(); - pt.X = center.X() + x * nCos - y * nSin; - pt.Y = center.Y() + y * nCos + x * nSin; -} - -static void lcl_FlipHFlipV(tools::Polygon aPoly, sal_Int32 nAngle, bool& rFlipH, bool& rFlipV) -{ - Point aStart = aPoly[0]; - Point aEnd = aPoly[aPoly.GetSize() - 1]; - - if (aStart.X() > aEnd.X() && aStart.Y() > aEnd.Y()) - { - if (nAngle) - { - if (nAngle == 90) - rFlipH = true; - if (nAngle == 270) - rFlipV = true; - } - else // 0° - { - rFlipH = true; - rFlipV = true; - } - } - - if (aStart.X() < aEnd.X() && aStart.Y() < aEnd.Y()) - { - if (nAngle) - { - if (nAngle != 270) - { - rFlipH = true; - rFlipV = true; - } - else - rFlipH = true; - } - } - - if (aStart.Y() < aEnd.Y() && aStart.X() > aEnd.X()) - { - if (nAngle) - { - if (nAngle == 180) - rFlipV = true; - if (nAngle == 270) - { - rFlipV = true; - rFlipH = true; - } - } - else // 0° - { - rFlipH = true; - } - } - - if (aStart.Y() > aEnd.Y() && aStart.X() < aEnd.X()) - { - if (nAngle) - { - if (nAngle == 90) - { - rFlipH = true; - rFlipV = true; - } - if (nAngle == 180) - rFlipH = true; - } - else // 0° - rFlipV = true; - } -} - -static sal_Int32 lcl_GetAngle(tools::Polygon aPoly) -{ - sal_Int32 nAngle; - Point aStartPoint = aPoly[0]; - Point aEndPoint = aPoly[aPoly.GetSize() - 1]; - if (aStartPoint.X() == aPoly[1].X()) - { - if ((aStartPoint.X() < aEndPoint.X() && aStartPoint.Y() > aEndPoint.Y()) - || (aStartPoint.X() > aEndPoint.X() && aStartPoint.Y() < aEndPoint.Y())) - { - nAngle = 90; - } - else - nAngle = 270; - } - else - { - if (aStartPoint.X() > aPoly[1].X()) - nAngle = 180; - else - nAngle = 0; - } - - return nAngle; -} - -// Adjust value decide the position, where the connector should turn. -static void lcl_GetConnectorAdjustValue(const Reference<XShape>& xShape, tools::Polygon aPoly, - ConnectorType eConnectorType, - std::vector<std::pair<sal_Int32, sal_Int32>>& rAvList) -{ - sal_Int32 nAdjCount = 0; - if (eConnectorType == ConnectorType_CURVE) - { - if (aPoly.GetSize() == 4) - { - if ((aPoly[0].X() == aPoly[1].X() && aPoly[2].X() == aPoly[3].X()) - || (aPoly[0].Y() == aPoly[1].Y() && aPoly[2].Y() == aPoly[3].Y())) - { - nAdjCount = 1; // curvedConnector3 - } - else - nAdjCount = 0; // curvedConnector2 - } - else - { - if ((aPoly[2].X() == aPoly[3].X() && aPoly[3].X() == aPoly[4].X()) - || (aPoly[2].Y() == aPoly[3].Y() && aPoly[3].Y() == aPoly[4].Y())) - { - nAdjCount = 3; // curvedConnector5 - } - else - nAdjCount = 2; // curvedConnector4 - } - } - else - { - switch (aPoly.GetSize()) - { - case 3: - nAdjCount = 0; // bentConnector2 - break; - case 4: - nAdjCount = 1; // bentConnector3 - break; - case 5: - nAdjCount = 2; // bentConnector4 - break; - case 6: - nAdjCount = 3; // bentConnector5 - break; - } - } - - if (nAdjCount) - { - sal_Int32 nAdjustValue; - Point aStart = aPoly[0]; - Point aEnd = aPoly[aPoly.GetSize() - 1]; - - for (sal_Int32 i = 1; i <= nAdjCount; ++i) - { - Point aPt = aPoly[i]; - - if (aEnd.Y() == aStart.Y()) - aEnd.setY(aStart.Y() + 1); - if (aEnd.X() == aStart.X()) - aEnd.setX(aStart.X() + 1); - - bool bVertical = aPoly[1].X() - aStart.X() != 0 ? true : false; - // vertical and horizon alternate - if (i % 2 == 1) - bVertical = !bVertical; - - if (eConnectorType == ConnectorType_CURVE) - { - awt::Size aSize = xShape->getSize(); - awt::Point aShapePosition = xShape->getPosition(); - tools::Rectangle aBoundRect = aPoly.GetBoundRect(); - - if (bVertical) - { - if ((aBoundRect.GetSize().Height() - aSize.Height) == 1) - aPt.setY(aPoly[i + 1].Y()); - else if (aStart.Y() > aPt.Y()) - aPt.setY(aShapePosition.Y); - else - aPt.setY(aShapePosition.Y + aSize.Height); - } - else - { - if ((aBoundRect.GetSize().Width() - aSize.Width) == 1) - aPt.setX(aPoly[i + 1].X()); - else if (aStart.X() > aPt.X()) - aPt.setX(aShapePosition.X); - else - aPt.setX(aShapePosition.X + aSize.Width); - } - } - - if (bVertical) - nAdjustValue = ((aPt.Y() - aStart.Y()) * 100000) / (aEnd.Y() - aStart.Y()); - else - nAdjustValue = ((aPt.X() - aStart.X()) * 100000) / (aEnd.X() - aStart.X()); - - rAvList.emplace_back(i, nAdjustValue); - } - } -} - ShapeExport& ShapeExport::WriteConnectorShape( const Reference< XShape >& xShape ) { bool bFlipH = false; bool bFlipV = false; - sal_Int32 nAngle = 0; SAL_INFO("oox.shape", "write connector shape"); FSHelperPtr pFS = GetFS(); - OUString sGeometry; - std::vector<std::pair<sal_Int32, sal_Int32>> aAdjustValueList; + const char* sGeometry = "line"; Reference< XPropertySet > rXPropSet( xShape, UNO_QUERY ); Reference< XPropertyState > rXPropState( xShape, UNO_QUERY ); awt::Point aStartPoint, aEndPoint; Reference< XShape > rXShapeA; Reference< XShape > rXShapeB; PropertyState eState; - ConnectorType eConnectorType = ConnectorType_STANDARD; - GET(eConnectorType, EdgeKind); + ConnectorType eConnectorType; + if( GETAD( EdgeKind ) ) { + mAny >>= eConnectorType; - switch( eConnectorType ) { - case ConnectorType_CURVE: - sGeometry = "curvedConnector"; - break; - case ConnectorType_STANDARD: - sGeometry = "bentConnector"; - break; - default: - case ConnectorType_LINE: - case ConnectorType_LINES: - sGeometry = "straightConnector1"; - break; - } + switch( eConnectorType ) { + case ConnectorType_CURVE: + sGeometry = "curvedConnector3"; + break; + case ConnectorType_STANDARD: + sGeometry = "bentConnector3"; + break; + default: + case ConnectorType_LINE: + case ConnectorType_LINES: + sGeometry = "straightConnector1"; + break; + } - if( GETAD( EdgeStartPoint ) ) { - mAny >>= aStartPoint; - if( GETAD( EdgeEndPoint ) ) { - mAny >>= aEndPoint; + if( GETAD( EdgeStartPoint ) ) { + mAny >>= aStartPoint; + if( GETAD( EdgeEndPoint ) ) { + mAny >>= aEndPoint; + } } + GET( rXShapeA, EdgeStartConnection ); + GET( rXShapeB, EdgeEndConnection ); } - GET( rXShapeA, EdgeStartConnection ); - GET( rXShapeB, EdgeEndConnection ); - // Position is relative to group in Word, but relative to anchor of group in API. if (GetDocumentType() == DOCUMENT_DOCX && !mbUserShapes && m_xParent.is()) { @@ -1691,40 +1464,17 @@ ShapeExport& ShapeExport::WriteConnectorShape( const Reference< XShape >& xShape aEndPoint.Y -= aParentPos.Y; } EscherConnectorListEntry aConnectorEntry( xShape, aStartPoint, rXShapeA, aEndPoint, rXShapeB ); - - if (eConnectorType == ConnectorType_CURVE || eConnectorType == ConnectorType_STANDARD) - { - tools::PolyPolygon aPolyPolygon = EscherPropertyContainer::GetPolyPolygon(xShape); - if (aPolyPolygon.Count() > 0) - { - tools::Polygon aPoly = aPolyPolygon.GetObject(0); - lcl_GetConnectorAdjustValue(xShape, aPoly, eConnectorType, aAdjustValueList); - nAngle = lcl_GetAngle(aPoly); - lcl_FlipHFlipV(aPoly, nAngle, bFlipH, bFlipV); - if (nAngle) - { - Point center((aEndPoint.X + aStartPoint.X) / 2, (aEndPoint.Y + aStartPoint.Y) / 2); - lcl_Rotate(nAngle, center, aStartPoint); - lcl_Rotate(nAngle, center, aEndPoint); - nAngle *= 60000; - } - sGeometry = sGeometry + OUString::number(aAdjustValueList.size() + 2); - } - } - tools::Rectangle aRect( Point( aStartPoint.X, aStartPoint.Y ), Point( aEndPoint.X, aEndPoint.Y ) ); if( aRect.getWidth() < 0 ) { + bFlipH = true; aRect.SetLeft(aEndPoint.X); aRect.setWidth( aStartPoint.X - aEndPoint.X ); - if (eConnectorType == ConnectorType_LINE) - bFlipH = true; } if( aRect.getHeight() < 0 ) { + bFlipV = true; aRect.SetTop(aEndPoint.Y); aRect.setHeight( aStartPoint.Y - aEndPoint.Y ); - if (eConnectorType == ConnectorType_LINE) - bFlipV = true; } // tdf#99810 connector shape (cxnSp) is not valid with namespace 'wps' @@ -1754,9 +1504,9 @@ ShapeExport& ShapeExport::WriteConnectorShape( const Reference< XShape >& xShape // visual shape properties pFS->startElementNS(mnXmlNamespace, XML_spPr); - WriteTransformation( xShape, aRect, XML_a, bFlipH, bFlipV, nAngle ); + WriteTransformation( xShape, aRect, XML_a, bFlipH, bFlipV ); // TODO: write adjustments (ppt export doesn't work well there either) - WritePresetShape( sGeometry.toUtf8(), aAdjustValueList); + WritePresetShape( sGeometry ); Reference< XPropertySet > xShapeProps( xShape, UNO_QUERY ); if( xShapeProps.is() ) WriteOutline( xShapeProps ); |