summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odpbin0 -> 17679 bytes
-rw-r--r--xmloff/qa/unit/draw.cxx76
-rw-r--r--xmloff/source/draw/ximpcustomshape.cxx32
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
new file mode 100644
index 000000000000..94a4e0b3a235
--- /dev/null
+++ b/xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odp
Binary files differ
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,