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 <noel.grandin@collabora.co.uk>
Reviewed-by: Jaume Pujantell <jaume.pujantell@collabora.com>
This commit is contained in:
Jaume Pujantell
2026-01-20 11:09:24 +01:00
parent 19182801fc
commit 85dbb4dc81
4 changed files with 60 additions and 4 deletions
Binary file not shown.
+18
View File
@@ -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: */
+13 -4
View File
@@ -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(
{
+29
View File
@@ -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)