diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx index 49178ebdc996..83c0f8bf3193 100644 --- a/include/xmloff/xmltoken.hxx +++ b/include/xmloff/xmltoken.hxx @@ -1655,6 +1655,7 @@ namespace xmloff::token { XML_SHADOW_OFFSET_Y, XML_SHADOW_SLANT, XML_SHADOW_TRANSPARENCY, + XML_SHADOW_BLUR, XML_SHAPE, XML_SHAPE_ID, XML_SHAPES, diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 607db7a33ae7..a5a44cc3e7fe 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -3618,7 +3618,7 @@ void DrawingML::WriteShapeEffect( const OUString& sName, const Sequence< Propert } else if( rOuterShdwProp.Name == "blurRad" ) { - sal_Int32 nVal = 0; + sal_Int64 nVal = 0; rOuterShdwProp.Value >>= nVal; aOuterShdwAttrList->add( XML_blurRad, OString::number( nVal ).getStr() ); } @@ -3802,16 +3802,20 @@ void DrawingML::WriteShapeEffects( const Reference< XPropertySet >& rXPropSet ) if( bHasShadow ) { Sequence< PropertyValue > aShadowGrabBag( 3 ); - Sequence< PropertyValue > aShadowAttribsGrabBag( 2 ); + Sequence< PropertyValue > aShadowAttribsGrabBag( 3 ); double dX = +0.0, dY = +0.0; + sal_Int32 nBlur =0; rXPropSet->getPropertyValue( "ShadowXDistance" ) >>= dX; rXPropSet->getPropertyValue( "ShadowYDistance" ) >>= dY; + rXPropSet->getPropertyValue( "ShadowBlur" ) >>= nBlur; aShadowAttribsGrabBag[0].Name = "dist"; aShadowAttribsGrabBag[0].Value <<= lcl_CalculateDist(dX, dY); aShadowAttribsGrabBag[1].Name = "dir"; aShadowAttribsGrabBag[1].Value <<= lcl_CalculateDir(dX, dY); + aShadowAttribsGrabBag[2].Name = "blurRad"; + aShadowAttribsGrabBag[2].Value <<= oox::drawingml::convertHmmToEmu(nBlur); aShadowGrabBag[0].Name = "Attribs"; aShadowGrabBag[0].Value <<= aShadowAttribsGrabBag; @@ -3836,8 +3840,11 @@ void DrawingML::WriteShapeEffects( const Reference< XPropertySet >& rXPropSet ) rOuterShdwProp.Value >>= aAttribsProps; double dX = +0.0, dY = +0.0; + sal_Int32 nBlur =0; rXPropSet->getPropertyValue( "ShadowXDistance" ) >>= dX; rXPropSet->getPropertyValue( "ShadowYDistance" ) >>= dY; + rXPropSet->getPropertyValue( "ShadowBlur" ) >>= nBlur; + for( auto& rAttribsProp : aAttribsProps ) { @@ -3849,6 +3856,10 @@ void DrawingML::WriteShapeEffects( const Reference< XPropertySet >& rXPropSet ) { rAttribsProp.Value <<= lcl_CalculateDir(dX, dY); } + else if( rAttribsProp.Name == "blurRad" ) + { + rAttribsProp.Value <<= oox::drawingml::convertHmmToEmu(nBlur); + } } rOuterShdwProp.Value <<= aAttribsProps; diff --git a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng index 90e240a5a2a1..bd66081734c1 100644 --- a/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng +++ b/schema/libreoffice/OpenDocument-schema-v1.3+libreoffice.rng @@ -344,6 +344,12 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. + + + + + + diff --git a/sd/qa/unit/data/odg/shadow-blur.odg b/sd/qa/unit/data/odg/shadow-blur.odg new file mode 100644 index 000000000000..a67b8e1866fc Binary files /dev/null and b/sd/qa/unit/data/odg/shadow-blur.odg differ diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index a3ff094b7f21..498443d12236 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -197,6 +197,7 @@ public: void testTdf132282(); void testTdf132201EffectOrder(); void testShapeSoftEdgeEffect(); + void testShapeShadowBlurEffect(); CPPUNIT_TEST_SUITE(SdOOXMLExportTest2); @@ -311,6 +312,7 @@ public: CPPUNIT_TEST(testTdf132282); CPPUNIT_TEST(testTdf132201EffectOrder); CPPUNIT_TEST(testShapeSoftEdgeEffect); + CPPUNIT_TEST(testShapeShadowBlurEffect); CPPUNIT_TEST_SUITE_END(); @@ -2911,6 +2913,20 @@ void SdOOXMLExportTest2::testShapeSoftEdgeEffect() CPPUNIT_ASSERT_EQUAL(sal_Int32(635), nRadius); // 18 pt } +void SdOOXMLExportTest2::testShapeShadowBlurEffect() +{ + auto xDocShRef + = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/shape-blur-effect.pptx"), PPTX); + xDocShRef = saveAndReload(xDocShRef.get(), PPTX); + uno::Reference xShape(getShapeFromPage(0, 0, xDocShRef)); + bool bHasShadow = false; + xShape->getPropertyValue("Shadow") >>= bHasShadow; + CPPUNIT_ASSERT(bHasShadow); + sal_Int32 nRadius = -1; + xShape->getPropertyValue("ShadowBlur") >>= nRadius; + CPPUNIT_ASSERT_EQUAL(sal_Int32(388), nRadius); // 11 pt +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx index a2186fae62af..a6ad545b3221 100644 --- a/sd/qa/unit/export-tests.cxx +++ b/sd/qa/unit/export-tests.cxx @@ -76,6 +76,7 @@ public: void testTdf126761(); void testGlow(); void testSoftEdges(); + void testShadowBlur(); CPPUNIT_TEST_SUITE(SdExportTest); @@ -112,6 +113,7 @@ public: CPPUNIT_TEST(testTdf126761); CPPUNIT_TEST(testGlow); CPPUNIT_TEST(testSoftEdges); + CPPUNIT_TEST(testShadowBlur); CPPUNIT_TEST_SUITE_END(); @@ -1307,6 +1309,29 @@ void SdExportTest::testSoftEdges() xDocShRef->DoClose(); } +void SdExportTest::testShadowBlur() +{ + auto xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/odg/shadow-blur.odg"), ODG); + utl::TempFile tempFile; + xDocShRef = saveAndReload(xDocShRef.get(), ODG, &tempFile); + uno::Reference xShape(getShapeFromPage(0, 0, xDocShRef)); + + sal_Int32 nRad = 0; + CPPUNIT_ASSERT(xShape->getPropertyValue("ShadowBlur") >>= nRad); + CPPUNIT_ASSERT_EQUAL(sal_Int32(388), nRad); // 11 pt = 388 Hmm + + xmlDocUniquePtr pXmlDoc = parseExport(tempFile, "content.xml"); + + assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[2]", + "family", "graphic"); + assertXPath( + pXmlDoc, + "/office:document-content/office:automatic-styles/style:style[2]/style:graphic-properties", + "shadow-blur", "0.388cm"); + + xDocShRef->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx index 8bec9a79adea..a3d8f8b7c51e 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx @@ -173,7 +173,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testShapeEffectPreservation, "shape-effect-p "algn", "tl"); assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:outerShdw", - "blurRad", "50800"); + "blurRad", "50760"); // because convertEMUtoHmm rounds fractions into nearest integer 50800 will be 50760 assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:outerShdw", "dir", "2700000"); @@ -196,7 +196,7 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testShapeEffectPreservation, "shape-effect-p "algn", "tl"); assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:outerShdw", - "blurRad", "114300"); + "blurRad", "114480"); // because convertEMUtoHmm rounds fractions into nearest integer 114300 will be 114480 assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:effectLst/a:outerShdw", "dir", "2700000"); diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx index 8d9a70f5e082..7773ac8ebcc6 100644 --- a/xmloff/source/core/xmltoken.cxx +++ b/xmloff/source/core/xmltoken.cxx @@ -1661,6 +1661,7 @@ namespace xmloff::token { TOKEN( "shadow-offset-y", XML_SHADOW_OFFSET_Y ), TOKEN( "shadow-slant", XML_SHADOW_SLANT ), TOKEN( "shadow-transparency", XML_SHADOW_TRANSPARENCY ), + TOKEN( "shadow-blur", XML_SHADOW_BLUR ), TOKEN( "shape", XML_SHAPE ), TOKEN( "shape-id", XML_SHAPE_ID ), TOKEN( "shapes", XML_SHAPES ), diff --git a/xmloff/source/draw/sdpropls.cxx b/xmloff/source/draw/sdpropls.cxx index 2adc5da00c6d..3f6c1a70a817 100644 --- a/xmloff/source/draw/sdpropls.cxx +++ b/xmloff/source/draw/sdpropls.cxx @@ -151,6 +151,7 @@ const XMLPropertyMapEntry aXMLSDProperties[] = GMAP( "ShadowYDistance", XML_NAMESPACE_DRAW, XML_SHADOW_OFFSET_Y, XML_TYPE_MEASURE, 0 ), GMAP( "ShadowColor", XML_NAMESPACE_DRAW, XML_SHADOW_COLOR, XML_TYPE_COLOR, 0 ), GMAP( "ShadowTransparence", XML_NAMESPACE_DRAW, XML_SHADOW_OPACITY, XML_TYPE_NEG_PERCENT, 0 ), + GMAPV( "ShadowBlur", XML_NAMESPACE_LO_EXT, XML_SHADOW_BLUR, XML_TYPE_MEASURE, 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED), // glow attributes GMAPV( "GlowEffectRadius", XML_NAMESPACE_LO_EXT, XML_GLOW_RADIUS, XML_TYPE_MEASURE , 0, SvtSaveOptions::ODFSVER_FUTURE_EXTENDED), diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt index 34b9af91e03c..0c67e23c3b50 100644 --- a/xmloff/source/token/tokens.txt +++ b/xmloff/source/token/tokens.txt @@ -1571,6 +1571,7 @@ shadow-offset-x shadow-offset-y shadow-slant shadow-transparency +shadow-blur shape shape-id shapes