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.henschel@t-online.de>
This commit is contained in:
Regina Henschel 2022-05-03 00:18:00 +02:00
parent 6f94aa6f1a
commit 8ad4fdb168
3 changed files with 104 additions and 4 deletions

Binary file not shown.

View file

@ -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: */

View file

@ -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,