filter/source/msfilter/escherex.cxx | 33 ++++++++++++++++++-------- filter/source/msfilter/util.cxx | 1 include/filter/msfilter/escherex.hxx | 3 +- sd/qa/unit/data/pptx/tdf162283.pptx |binary sd/qa/unit/export-tests.cxx | 44 +++++++++++++++++++++++++++++++++++ sd/source/filter/eppt/epptso.cxx | 27 +++++++++++++++++++-- 6 files changed, 95 insertions(+), 13 deletions(-)
New commits: commit 38f6f44a2cc854e652c09bbd7ee3511b5fed3f8e Author: Tibor Nagy <tibor.nagy.ext...@allotropia.de> AuthorDate: Tue Aug 20 01:22:51 2024 +0200 Commit: Nagy Tibor <tibor.nagy.ext...@allotropia.de> CommitDate: Wed Aug 21 12:57:57 2024 +0200 tdf#162283 PPT export: fix regression... ...was made by: Iefb9d97e0eb10a04c39b515b11e549aeb7be8f25 This regression occurred because there is a feature in MSO that allows the shape of a placeholder to be changed. In this case, the placeholder is converted into a custom shape after the import and saving custom shape from .pptx to .ppt didn't work. Change-Id: I85305b65742da8b4966d4956b9141c59b4563973 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172091 Reviewed-by: Nagy Tibor <tibor.nagy.ext...@allotropia.de> Tested-by: Jenkins diff --git a/filter/source/msfilter/escherex.cxx b/filter/source/msfilter/escherex.cxx index 0e251dfac83c..d3be3f16906b 100644 --- a/filter/source/msfilter/escherex.cxx +++ b/filter/source/msfilter/escherex.cxx @@ -2578,7 +2578,7 @@ bool EscherPropertyContainer::GetAdjustmentValue( const drawing::EnhancedCustomS return true; } -void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeType, const uno::Reference< drawing::XShape > & rXShape ) +void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeType, const uno::Reference< drawing::XShape > & rXShape, bool bOOXML ) { uno::Reference< beans::XPropertySet > aXPropSet( rXShape, uno::UNO_QUERY ); if ( !aXPropSet.is() ) @@ -2618,6 +2618,14 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT rSdrObjCustomShape, eShapeType)); + bool bUseDefaultObject = false; + if (bOOXML) + { + const mso_CustomShape* pDefCustomShape = GetCustomShapeContent(eShapeType); + if(pDefCustomShape) + bUseDefaultObject = true; + } + // convert property "Equations" into std::vector< EnhancedCustomShapeEquationEquation > std::vector< EnhancedCustomShapeEquation > aEquations; std::vector< sal_Int32 > aEquationOrder; @@ -2632,7 +2640,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT const beans::PropertyValue& rProp = aGeoPropSeq[ i ]; if ( rProp.Name == sViewBox ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { awt::Rectangle aViewBox; if ( rProp.Value >>= aViewBox ) @@ -2949,7 +2957,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rProp.Name == sEquations ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { sal_uInt16 nElements = static_cast<sal_uInt16>(aEquations.size()); if ( nElements ) @@ -3039,7 +3047,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rrProp.Name == "Coordinates" ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { aPathCoordinatesProp = rrProp.Value; bPathCoordinatesProp = true; @@ -3047,7 +3055,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rrProp.Name == "GluePoints" ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aGluePoints; if ( rrProp.Value >>= aGluePoints ) @@ -3087,7 +3095,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rrProp.Name == "Segments" ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments; if ( rrProp.Value >>= aSegments ) @@ -3207,7 +3215,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rrProp.Name == "StretchX" ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { sal_Int32 nStretchX = 0; if ( rrProp.Value >>= nStretchX ) @@ -3216,7 +3224,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rrProp.Name == "StretchY" ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { sal_Int32 nStretchY = 0; if ( rrProp.Value >>= nStretchY ) @@ -3225,7 +3233,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rrProp.Name == "TextFrames" ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { uno::Sequence<drawing::EnhancedCustomShapeTextFrame> aPathTextFrames; if ( rrProp.Value >>= aPathTextFrames ) @@ -3470,7 +3478,7 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT } else if ( rProp.Name == sHandles ) { - if ( !bIsDefaultObject ) + if (!bIsDefaultObject && !bUseDefaultObject) { bPredefinedHandlesUsed = false; if ( rProp.Value >>= aHandlesPropSeq ) @@ -3657,7 +3665,12 @@ void EscherPropertyContainer::CreateCustomShapeProperties( const MSO_SPT eShapeT sal_Int32 k, nValue = 0, nAdjustmentValues = aAdjustmentSeq.getLength(); for ( k = 0; k < nAdjustmentValues; k++ ) if( GetAdjustmentValue( aAdjustmentSeq[ k ], k, nAdjustmentsWhichNeedsToBeConverted, nValue ) ) + { + if (bUseDefaultObject) + nValue = 21600 * (nValue / 100000.00); + AddOpt( static_cast<sal_uInt16>( DFF_Prop_adjustValue + k ), static_cast<sal_uInt32>(nValue) ); + } } } if( !bPathCoordinatesProp ) diff --git a/filter/source/msfilter/util.cxx b/filter/source/msfilter/util.cxx index 2415f3ea4bcb..837a33a67342 100644 --- a/filter/source/msfilter/util.cxx +++ b/filter/source/msfilter/util.cxx @@ -1277,6 +1277,7 @@ MSO_SPT GETVMLShapeType(std::u16string_view aType) {"actionButtonMovie", mso_sptActionButtonMovie}, {"hostControl", mso_sptHostControl}, {"textBox", mso_sptTextBox}, + {"roundRect", mso_sptRoundRectangle}, }; auto i(aDMLToVMLMap.find(GetOOXMLPresetGeometry(aType))); diff --git a/include/filter/msfilter/escherex.hxx b/include/filter/msfilter/escherex.hxx index 196dc7918f6e..91606bca13a2 100644 --- a/include/filter/msfilter/escherex.hxx +++ b/include/filter/msfilter/escherex.hxx @@ -824,7 +824,8 @@ public: // creates all necessary CustomShape properties, this includes also Text-, Shadow-, Fill-, and LineProperties void CreateCustomShapeProperties( const MSO_SPT eShapeType, - const css::uno::Reference< css::drawing::XShape > & + const css::uno::Reference< css::drawing::XShape > &, + bool bOOXML = false ); bool IsFontWork() const; diff --git a/sd/qa/unit/data/pptx/tdf162283.pptx b/sd/qa/unit/data/pptx/tdf162283.pptx new file mode 100644 index 000000000000..414937d321a9 Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf162283.pptx differ diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx index 69b9db9d58f8..04ce872ffe10 100644 --- a/sd/qa/unit/export-tests.cxx +++ b/sd/qa/unit/export-tests.cxx @@ -14,6 +14,7 @@ #include <sdpage.hxx> #include <comphelper/sequenceashashmap.hxx> +#include <comphelper/sequence.hxx> #include <editeng/editobj.hxx> #include <editeng/outlobj.hxx> #include <editeng/colritem.hxx> @@ -30,6 +31,7 @@ #include <com/sun/star/drawing/XDrawPage.hpp> #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/drawing/XMasterPagesSupplier.hpp> +#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/awt/XBitmap.hpp> #include <com/sun/star/graphic/XGraphic.hpp> @@ -199,6 +201,48 @@ CPPUNIT_TEST_FIXTURE(SdExportTest, testTransparentBackground) checkFontAttributes<Color, SvxColorItem>(pObj2, COL_YELLOW, EE_CHAR_BKGCOLOR); } +CPPUNIT_TEST_FIXTURE(SdExportTest, testTdf162283) +{ + createSdImpressDoc("pptx/tdf162283.pptx"); + saveAndReload(u"MS PowerPoint 97"_ustr); + + uno::Reference<drawing::XDrawPage> xPage(getPage(0)); + uno::Reference<beans::XPropertySet> xPropSet(getShape(0, xPage)); + + CPPUNIT_ASSERT(xPropSet.is()); + auto aGeomPropSeq = xPropSet->getPropertyValue(u"CustomShapeGeometry"_ustr) + .get<uno::Sequence<beans::PropertyValue>>(); + auto aGeomPropVec + = comphelper::sequenceToContainer<std::vector<beans::PropertyValue>>(aGeomPropSeq); + + sal_Int32 nWidth = 0, nHeight = 0, nAdjValue = 0; + + auto aIt1 = std::find_if( + aGeomPropVec.begin(), aGeomPropVec.end(), + [](const beans::PropertyValue& rValue) { return rValue.Name == u"ViewBox"_ustr; }); + if (aIt1 != aGeomPropVec.end()) + { + awt::Rectangle aViewBox; + aIt1->Value >>= aViewBox; + nWidth = aViewBox.Width; + nHeight = aViewBox.Height; + } + + auto aIt2 = std::find_if( + aGeomPropVec.begin(), aGeomPropVec.end(), + [](const beans::PropertyValue& rValue) { return rValue.Name == u"AdjustmentValues"_ustr; }); + if (aIt2 != aGeomPropVec.end()) + { + uno::Sequence<drawing::EnhancedCustomShapeAdjustmentValue> aAdjustment; + aIt2->Value >>= aAdjustment; + aAdjustment[0].Value >>= nAdjValue; + } + + CPPUNIT_ASSERT_EQUAL(sal_Int32(21600), nWidth); + CPPUNIT_ASSERT_EQUAL(sal_Int32(21600), nHeight); + CPPUNIT_ASSERT_EQUAL(sal_Int32(6688), nAdjValue); +} + CPPUNIT_TEST_FIXTURE(SdExportTest, testDecorative) { createSdImpressDoc("pptx/tdf141058-1.pptx"); diff --git a/sd/source/filter/eppt/epptso.cxx b/sd/source/filter/eppt/epptso.cxx index 87510606c43b..a5305e60404c 100644 --- a/sd/source/filter/eppt/epptso.cxx +++ b/sd/source/filter/eppt/epptso.cxx @@ -1738,7 +1738,30 @@ void PPTWriter::ImplWritePage( const PHLayout& rLayout, EscherSolverContainer& a mpPptEscherEx->OpenContainer( ESCHER_SpContainer ); ShapeFlag nMirrorFlags; OUString sCustomShapeType; - MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( mXShape, nMirrorFlags, sCustomShapeType ); + bool bOOXML = false; + css::uno::Any aAny; + if (GetPropertyValue(aAny, mXPropSet, u"CustomShapeGeometry"_ustr, true)) + { + uno::Sequence<beans::PropertyValue> aGeoPropSeq; + if (aAny >>= aGeoPropSeq) + { + sal_Int32 i, nCount = aGeoPropSeq.getLength(); + for (i = 0; i < nCount; ++i) + { + const beans::PropertyValue& rProp = aGeoPropSeq[i]; + if (rProp.Name == "Type") + { + if (rProp.Value >>= sCustomShapeType) + { + if (sCustomShapeType.startsWith("ooxml")) + bOOXML = true; + break; + } + } + } + } + } + MSO_SPT eShapeType = EscherPropertyContainer::GetCustomShapeType( mXShape, nMirrorFlags, sCustomShapeType, bOOXML ); if ( sCustomShapeType == "col-502ad400" || sCustomShapeType == "col-60da8460" ) { // sj: creating metafile for customshapes that can't be saved to ms format properly ImplCreateShape( ESCHER_ShpInst_PictureFrame, @@ -1763,7 +1786,7 @@ void PPTWriter::ImplWritePage( const PHLayout& rLayout, EscherSolverContainer& a ImplCreateShape( eShapeType, nMirrorFlags | ShapeFlag::HaveAnchor | ShapeFlag::HaveShapeProperty, aSolverContainer ); - aPropOpt.CreateCustomShapeProperties( eShapeType, mXShape ); + aPropOpt.CreateCustomShapeProperties( eShapeType, mXShape, bOOXML ); aPropOpt.CreateFillProperties( mXPropSet, true, mXShape); if ( ImplGetText() ) {