diff options
-rw-r--r-- | xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odp | bin | 0 -> 17679 bytes | |||
-rw-r--r-- | xmloff/qa/unit/draw.cxx | 76 | ||||
-rw-r--r-- | xmloff/source/draw/ximpcustomshape.cxx | 32 |
3 files changed, 104 insertions, 4 deletions
diff --git a/xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odp b/xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odp Binary files differnew file mode 100644 index 000000000000..94a4e0b3a235 --- /dev/null +++ b/xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odp diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index d27a7339a4bc..e45f5bbb444b 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -17,6 +17,8 @@ #include <com/sun/star/frame/XStorable.hpp> #include <com/sun/star/packages/zip/ZipFileAccess.hpp> #include <com/sun/star/drawing/EnhancedCustomShapeMetalType.hpp> +#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp> +#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp> #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/drawing/XMasterPageTarget.hpp> #include <com/sun/star/util/Color.hpp> @@ -408,6 +410,80 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularity) SetODFDefaultVersion(nCurrentODFVersion); } +namespace +{ +bool lcl_getShapeSegments(uno::Sequence<drawing::EnhancedCustomShapeSegment>& rSegments, + const uno::Reference<drawing::XShape>& xShape) +{ + uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY_THROW); + uno::Any anotherAny = xShapeProps->getPropertyValue("CustomShapeGeometry"); + uno::Sequence<beans::PropertyValue> aCustomShapeGeometry; + if (!(anotherAny >>= aCustomShapeGeometry)) + return false; + uno::Sequence<beans::PropertyValue> aPathProps; + for (beans::PropertyValue const& rProp : std::as_const(aCustomShapeGeometry)) + { + if (rProp.Name == "Path") + { + rProp.Value >>= aPathProps; + break; + } + } + + for (beans::PropertyValue const& rProp : std::as_const(aPathProps)) + { + if (rProp.Name == "Segments") + { + rProp.Value >>= rSegments; + break; + } + } + if (rSegments.getLength() > 2) + return true; + else + return false; +} +} + +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testTdf148714_CurvedArrowsOld) +{ + // Load a document with CurveArrow shapes with faulty path as written by older LO versions. + OUString sURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf148714_CurvedArrowsOld.odp"; + getComponent() = loadFromDesktop(sURL, "com.sun.star.presentation.PresentationDocument"); + + // Make sure, that the error has been corrected on opening. + for (sal_Int32 nShapeIndex = 0; nShapeIndex < 4; nShapeIndex++) + { + uno::Reference<drawing::XShape> xShape(getShape(nShapeIndex)); + uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments; + CPPUNIT_ASSERT(lcl_getShapeSegments(aSegments, xShape)); + + if (nShapeIndex == 0 || nShapeIndex == 3) + { + // curvedDownArrow or curvedLeftArrow. Segments should start with VW. Without fix it was + // V with count 2, which means VV. + CPPUNIT_ASSERT_EQUAL( + sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC), + aSegments[0].Command); + CPPUNIT_ASSERT_EQUAL(sal_Int16(1), aSegments[0].Count); + CPPUNIT_ASSERT_EQUAL( + sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO), + aSegments[1].Command); + CPPUNIT_ASSERT_EQUAL(sal_Int16(1), aSegments[1].Count); + } + else + { + // curvedUpArrow or curvedRightArrow. Segments should start with BA. Without fix is was + // B with count 2, which means BB. + CPPUNIT_ASSERT_EQUAL(sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::ARC), + aSegments[0].Command); + CPPUNIT_ASSERT_EQUAL(sal_Int16(1), aSegments[0].Count); + CPPUNIT_ASSERT_EQUAL(sal_Int16(drawing::EnhancedCustomShapeSegmentCommand::ARCTO), + aSegments[1].Command); + CPPUNIT_ASSERT_EQUAL(sal_Int16(1), aSegments[1].Count); + } + } +} CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/xmloff/source/draw/ximpcustomshape.cxx b/xmloff/source/draw/ximpcustomshape.cxx index 6f4c586a9626..b50172624eec 100644 --- a/xmloff/source/draw/ximpcustomshape.cxx +++ b/xmloff/source/draw/ximpcustomshape.cxx @@ -577,8 +577,9 @@ static void GetEnhancedRectangleSequence( std::vector< css::beans::PropertyValue } } -static void GetEnhancedPath( std::vector< css::beans::PropertyValue >& rDest, // e.g. draw:enhanced-path - const OUString& rValue ) +static void +GetEnhancedPath(std::vector<css::beans::PropertyValue>& rDest, // e.g. draw:enhanced-path + const OUString& rValue, std::u16string_view rType) { std::vector< css::drawing::EnhancedCustomShapeParameterPair > vCoordinates; std::vector< css::drawing::EnhancedCustomShapeSegment > vSegments; @@ -820,6 +821,22 @@ static void GetEnhancedPath( std::vector< css::beans::PropertyValue >& rDest, } } + // Corrections for wrong paths in curvedArrow shapes written by older LO versions + if (!vSegments.empty() + && (rType == u"mso-spt102" || rType == u"mso-spt103" || rType == u"mso-spt104" + || rType == u"mso-spt105") + && vSegments[0].Count == 2) + { + vSegments[0].Count = 1; + css::drawing::EnhancedCustomShapeSegment aSegment; + aSegment.Count = 1; + aSegment.Command + = vSegments[0].Command == css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARC + ? css::drawing::EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO + : css::drawing::EnhancedCustomShapeSegmentCommand::ARCTO; + vSegments.insert(vSegments.begin() + 1, aSegment); + } + // adding the Coordinates property beans::PropertyValue aProp; aProp.Name = EASGet( EAS_Coordinates ); @@ -868,12 +885,17 @@ void XMLEnhancedCustomShapeContext::startFastElement( { sal_Int32 nAttrNumber; std::optional<std::string_view> oSpecularityValue; // for postpone extrusion-specularity + std::optional<OUString> oPathValue; // for postpone GetEnhancedPath; + OUString sType("non-primitive"); // default in ODF for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) ) { switch( EASGet( aIter.getToken() ) ) { case EAS_type : - GetString( mrCustomShapeGeometry, aIter.toString(), EAS_Type ); + { + sType = aIter.toString(); + GetString( mrCustomShapeGeometry, sType, EAS_Type ); + } break; case EAS_mirror_horizontal : GetBool( mrCustomShapeGeometry, aIter.toView(), EAS_MirroredX ); @@ -1054,7 +1076,7 @@ void XMLEnhancedCustomShapeContext::startFastElement( GetBool( maExtrusion, aIter.toView(), EAS_Color ); break; case EAS_enhanced_path : - GetEnhancedPath( maPath, aIter.toString() ); + oPathValue = aIter.toString(); break; case EAS_path_stretchpoint_x : { @@ -1133,6 +1155,8 @@ void XMLEnhancedCustomShapeContext::startFastElement( } if (oSpecularityValue) GetDoublePercentage( maExtrusion, *oSpecularityValue, EAS_Specularity ); + if (oPathValue) + GetEnhancedPath(maPath, *oPathValue, sType); } static void SdXMLCustomShapePropertyMerge( std::vector< css::beans::PropertyValue >& rPropVec, |