oox/qa/unit/data/tdf170095.pptx |binary oox/qa/unit/shape.cxx | 18 ++++++++++++++++++ oox/source/drawingml/shape.cxx | 17 +++++++++++++---- svx/source/svdraw/svdobj.cxx | 29 +++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-)
New commits: commit 85dbb4dc81bed0b55a1bfbc5dce221b98eaf70d1 Author: Jaume Pujantell <[email protected]> AuthorDate: Tue Dec 23 09:26:12 2025 +0100 Commit: Jaume Pujantell <[email protected]> CommitDate: Tue Jan 20 11:09:24 2026 +0100 tdf#170095 override soft edge if there are 3D effects In OOXML, 3D effects override the soft-edge effect. Currently in LO 3D effects are not implemented, they are just remembered in a grabbag. To bring LO's behavior closer to other software, if when loaded there are both 3D effects and soft edge effect we ignore the soft edge effect. And if, while editing, a user adds soft edge effect then we dumb the remembered 3D effects in the grabbag. Change-Id: I2f59422d25c24bb4f9042694e0315bb15a2ac4c5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197526 Tested-by: Jenkins Reviewed-by: Noel Grandin <[email protected]> Reviewed-by: Jaume Pujantell <[email protected]> diff --git a/oox/qa/unit/data/tdf170095.pptx b/oox/qa/unit/data/tdf170095.pptx new file mode 100644 index 000000000000..65bf6535bb48 Binary files /dev/null and b/oox/qa/unit/data/tdf170095.pptx differ diff --git a/oox/qa/unit/shape.cxx b/oox/qa/unit/shape.cxx index fd1ac1faca0b..f3bc4ed12832 100644 --- a/oox/qa/unit/shape.cxx +++ b/oox/qa/unit/shape.cxx @@ -1079,6 +1079,24 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, testDigitGuideName_mathEqual) CPPUNIT_ASSERT_DOUBLES_EQUAL(10000.0, fBoundRectHeight, 5); } } + +CPPUNIT_TEST_FIXTURE(OoxShapeTest, testTdf170095SoftEdge3D) +{ + // Load file with a shape with both soft edge and 3D effects + loadFromFile(u"tdf170095.pptx"); + + // Then make sure the shape has no soft edge: + uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); + sal_Int32 nSoftEdgeRad{}; + xShape->getPropertyValue(u"SoftEdgeRadius"_ustr) >>= nSoftEdgeRad; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 + // - Actual : 882 + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nSoftEdgeRad); +} CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 1029ca1eccb9..68a7565e27e7 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -1634,6 +1634,18 @@ Reference< XShape > const & Shape::createAndInsert( aShapeProps.setProperty(PROP_CharHeight, GetFontHeight( mpMasterTextListStyle->getListStyle()[0].getTextCharacterProperties().moHeight.value() )); } + Sequence<PropertyValue> aCamera3DEffects = get3DProperties().getCameraAttributes(); + Sequence<PropertyValue> aLightRig3DEffects = get3DProperties().getLightRigAttributes(); + Sequence<PropertyValue> aShape3DEffects + = get3DProperties().getShape3DAttributes(rGraphicHelper, nFillPhClr); + bool bHas3DProps = aCamera3DEffects.hasElements() || aLightRig3DEffects.hasElements() + || aShape3DEffects.hasElements(); + if (bHas3DProps) + { + // 3D properties override softeEdge + getEffectProperties().maSoftEdge.moRad = 0; + } + // applying properties aShapeProps.assignUsed( getShapeProperties() ); aShapeProps.assignUsed( maDefaultShapeProperties ); @@ -2027,10 +2039,7 @@ Reference< XShape > const & Shape::createAndInsert( } // add 3D effects if any to GrabBag. They are still used in export. - Sequence< PropertyValue > aCamera3DEffects = get3DProperties().getCameraAttributes(); - Sequence< PropertyValue > aLightRig3DEffects = get3DProperties().getLightRigAttributes(); - Sequence< PropertyValue > aShape3DEffects = get3DProperties().getShape3DAttributes( rGraphicHelper, nFillPhClr ); - if( aCamera3DEffects.hasElements() || aLightRig3DEffects.hasElements() || aShape3DEffects.hasElements() ) + if (bHas3DProps) { uno::Sequence<beans::PropertyValue> a3DEffectsGrabBag = comphelper::InitPropertySequence( { diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index 8214ce283ae0..a289c617298f 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -36,6 +36,7 @@ #include <drawinglayer/processor2d/contourextractor2d.hxx> #include <drawinglayer/processor2d/linegeometryextractor2d.hxx> #include <comphelper/processfactory.hxx> +#include <comphelper/sequence.hxx> #include <editeng/editeng.hxx> #include <editeng/outlobj.hxx> #include <o3tl/deleter.hxx> @@ -2060,6 +2061,34 @@ const SfxPoolItem& SdrObject::GetMergedItem(const sal_uInt16 nWhich) const void SdrObject::SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, bool bClearAllItems) { GetProperties().SetMergedItemSetAndBroadcast(rSet, bClearAllItems); + + const SdrMetricItem* pItem; + const bool bSetSoftEdge + = (SfxItemState::SET == rSet.GetItemState(SDRATTR_SOFTEDGE_RADIUS, true, &pItem) + && pItem->GetValue() > 0); + if (bSetSoftEdge) + { + // Remove 3D grabbag + try + { + css::uno::Any aAnyGrabBag; + GetGrabBagItem(aAnyGrabBag); + uno::Sequence<beans::PropertyValue> aSeqGrabBag + = aAnyGrabBag.get<uno::Sequence<beans::PropertyValue>>(); + auto it = std::find_if(aSeqGrabBag.begin(), aSeqGrabBag.end(), + [](const beans::PropertyValue& rProp) { + return rProp.Name == u"3DEffectProperties"_ustr; + }); + if (it == aSeqGrabBag.end()) + return; + comphelper::removeElementAt(aSeqGrabBag, it - aSeqGrabBag.begin()); + SetGrabBagItem(css::uno::Any(aSeqGrabBag)); + } + catch (const css::uno::Exception&) + { + // Grab bag not found, nothing to do + } + } } void SdrObject::ApplyNotPersistAttr(const SfxItemSet& rAttr)
