xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odp |binary
 xmloff/qa/unit/draw.cxx                           |   76 ++++++++++++++++++++++
 xmloff/source/draw/ximpcustomshape.cxx            |   32 ++++++++-
 3 files changed, 104 insertions(+), 4 deletions(-)

New commits:
commit 8ad4fdb1687e705e31d9a4f30b385d50b91def08
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Tue May 3 00:18:00 2022 +0200
Commit:     Regina Henschel <rb.hensc...@t-online.de>
CommitDate: Tue May 3 18:54:49 2022 +0200

    tdf#148714 Repair path in older CurvedArrow shapes
    
    The CurvedArrow shapes had an error in their enhanced-path. The error
    was fixed in the geometry definition with commit 4cfe4699. But the
    wrong path was written to file markup. This patch repairs the path in
    shapes in documents written before the fix of the geometry definition.
    
    Change-Id: I6d7bc3b4ec4a61f16ce5dea3d352575525850b80
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133740
    Tested-by: Jenkins
    Reviewed-by: Regina Henschel <rb.hensc...@t-online.de>

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
Binary files /dev/null and b/xmloff/qa/unit/data/tdf148714_CurvedArrowsOld.odp 
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,

Reply via email to