diff options
-rw-r--r-- | include/oox/drawingml/effectproperties.hxx | 7 | ||||
-rw-r--r-- | include/oox/export/drawingml.hxx | 1 | ||||
-rw-r--r-- | oox/source/drawingml/effectproperties.cxx | 30 | ||||
-rw-r--r-- | oox/source/drawingml/effectpropertiescontext.cxx | 29 | ||||
-rw-r--r-- | oox/source/drawingml/shape.cxx | 27 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 118 | ||||
-rw-r--r-- | oox/source/export/shapes.cxx | 1 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/shape-effect-preservation.docx | bin | 0 -> 17276 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 59 |
9 files changed, 272 insertions, 0 deletions
diff --git a/include/oox/drawingml/effectproperties.hxx b/include/oox/drawingml/effectproperties.hxx index 83519c0221a7..618c7b90fe38 100644 --- a/include/oox/drawingml/effectproperties.hxx +++ b/include/oox/drawingml/effectproperties.hxx @@ -34,6 +34,10 @@ struct OOX_DLLPUBLIC EffectProperties { EffectShadowProperties maShadow; + /** Store unsupported effect type name and its attributes */ + OptValue< OUString > msUnsupportedEffectName; + std::vector< css::beans::PropertyValue > maUnsupportedEffectAttribs; + /** Overwrites all members that are explicitly set in rSourceProps. */ void assignUsed( const EffectProperties& rSourceProps ); @@ -41,6 +45,9 @@ struct OOX_DLLPUBLIC EffectProperties void pushToPropMap( PropertyMap& rPropMap, const GraphicHelper& rGraphicHelper ) const; + + void appendUnsupportedEffectAttrib( const OUString& aKey, const css::uno::Any& aValue ); + css::beans::PropertyValue getUnsupportedEffect(); }; diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 3efcf93bbcb6..7793e6bff2a3 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -173,6 +173,7 @@ public: void WritePolyPolygon( const PolyPolygon& rPolyPolygon ); void WriteFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet ); void WriteShapeStyle( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); + void WriteShapeEffects( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); static void ResetCounters(); diff --git a/oox/source/drawingml/effectproperties.cxx b/oox/source/drawingml/effectproperties.cxx index 7e89726abf14..be3b3d00cd18 100644 --- a/oox/source/drawingml/effectproperties.cxx +++ b/oox/source/drawingml/effectproperties.cxx @@ -30,6 +30,8 @@ void EffectShadowProperties::assignUsed(const EffectShadowProperties& rSourcePro void EffectProperties::assignUsed( const EffectProperties& rSourceProps ) { maShadow.assignUsed(rSourceProps.maShadow); + msUnsupportedEffectName.assignIfUsed( rSourceProps.msUnsupportedEffectName ); + maUnsupportedEffectAttribs = rSourceProps.maUnsupportedEffectAttribs; } void EffectProperties::pushToPropMap( PropertyMap& rPropMap, @@ -51,6 +53,34 @@ void EffectProperties::pushToPropMap( PropertyMap& rPropMap, } } +void EffectProperties::appendUnsupportedEffectAttrib( const OUString& aKey, const css::uno::Any& aValue ) +{ + css::beans::PropertyValue aProperty; + aProperty.Name = aKey; + aProperty.Value = aValue; + maUnsupportedEffectAttribs.push_back(aProperty); +} + +css::beans::PropertyValue EffectProperties::getUnsupportedEffect() +{ + css::beans::PropertyValue pRet; + if(!msUnsupportedEffectName.has()) + return pRet; + + css::uno::Sequence<css::beans::PropertyValue> aSeq(maUnsupportedEffectAttribs.size()); + css::beans::PropertyValue* pSeq = aSeq.getArray(); + for (std::vector<css::beans::PropertyValue>::iterator i = maUnsupportedEffectAttribs.begin(); i != maUnsupportedEffectAttribs.end(); ++i) + *pSeq++ = *i; + + pRet.Name = msUnsupportedEffectName.use(); + pRet.Value = css::uno::Any( aSeq ); + + msUnsupportedEffectName.reset(); + maUnsupportedEffectAttribs.clear(); + + return pRet; +} + } // namespace drawingml diff --git a/oox/source/drawingml/effectpropertiescontext.cxx b/oox/source/drawingml/effectpropertiescontext.cxx index 53997888e6aa..705adb046d18 100644 --- a/oox/source/drawingml/effectpropertiescontext.cxx +++ b/oox/source/drawingml/effectpropertiescontext.cxx @@ -39,6 +39,35 @@ ContextHandlerRef EffectPropertiesContext::onCreateContext( sal_Int32 nElement, { case A_TOKEN( outerShdw ): { + mrEffectProperties.msUnsupportedEffectName = "outerShdw"; + if( rAttribs.hasAttribute( XML_algn ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "algn", + makeAny( rAttribs.getString( XML_algn, "" ) ) ); + if( rAttribs.hasAttribute( XML_blurRad ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "blurRad", + makeAny( rAttribs.getInteger( XML_blurRad, 0 ) ) ); + if( rAttribs.hasAttribute( XML_dir ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "dir", + makeAny( rAttribs.getInteger( XML_dir, 0 ) ) ); + if( rAttribs.hasAttribute( XML_dist ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "dist", + makeAny( rAttribs.getInteger( XML_dist, 0 ) ) ); + if( rAttribs.hasAttribute( XML_kx ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "kx", + makeAny( rAttribs.getInteger( XML_kx, 0 ) ) ); + if( rAttribs.hasAttribute( XML_ky ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "ky", + makeAny( rAttribs.getInteger( XML_ky, 0 ) ) ); + if( rAttribs.hasAttribute( XML_rotWithShape ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "rotWithShape", + makeAny( rAttribs.getInteger( XML_rotWithShape, 0 ) ) ); + if( rAttribs.hasAttribute( XML_sx ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "sx", + makeAny( rAttribs.getInteger( XML_sx, 0 ) ) ); + if( rAttribs.hasAttribute( XML_sy ) ) + mrEffectProperties.appendUnsupportedEffectAttrib( "sy", + makeAny( rAttribs.getInteger( XML_sy, 0 ) ) ); + mrEffectProperties.maShadow.moShadowDist = rAttribs.getInteger( XML_dist, 0 ); mrEffectProperties.maShadow.moShadowDir = rAttribs.getInteger( XML_dir, 0 ); return new ColorContext( *this, mrEffectProperties.maShadow.moShadowColor ); diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 1d0d4525801f..d3964be2f862 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -893,6 +893,33 @@ Reference< XShape > Shape::createAndInsert( putPropertyToGrabBag( "GradFillDefinition", Any( aGradientStops ) ); putPropertyToGrabBag( "OriginalGradFill", aShapeProps.getProperty(PROP_FillGradient) ); } + + // store unsupported effect attributes in the grab bag + PropertyValue aEffect = aEffectProperties.getUnsupportedEffect(); + if( aEffect.Name != "" ) + { + Sequence< PropertyValue > aEffectsGrabBag( 3 ); + PUT_PROP( aEffectsGrabBag, 0, aEffect.Name, aEffect.Value ); + + OUString sColorScheme = aEffectProperties.maShadow.moShadowColor.getSchemeName(); + if( sColorScheme.isEmpty() ) + { + // RGB color and transparency value + PUT_PROP( aEffectsGrabBag, 1, "ShadowRgbClr", + aEffectProperties.maShadow.moShadowColor.getColor( rGraphicHelper, nFillPhClr ) ); + PUT_PROP( aEffectsGrabBag, 2, "ShadowRgbClrTransparency", + aEffectProperties.maShadow.moShadowColor.getTransparency() ); + } + else + { + // scheme color with name and transformations + PUT_PROP( aEffectsGrabBag, 1, "ShadowColorSchemeClr", sColorScheme ); + PUT_PROP( aEffectsGrabBag, 2, "ShadowColorTransformations", + aEffectProperties.maShadow.moShadowColor.getTransformations() ); + } + + putPropertyToGrabBag( "EffectProperties", Any( aEffectsGrabBag ) ); + } } // These can have a custom geometry, so position should be set here, diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index fb0cd6a5df5b..a14cf72bc32d 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -2076,6 +2076,124 @@ void DrawingML::WriteShapeStyle( Reference< XPropertySet > xPropSet ) mpFS->singleElementNS( XML_a, XML_fontRef, XML_idx, "minor", FSEND ); } +void DrawingML::WriteShapeEffects( Reference< XPropertySet > rXPropSet ) +{ + if( !GetProperty( rXPropSet, "InteropGrabBag" ) ) + return; + + Sequence< PropertyValue > aGrabBag, aEffectProps; + mAny >>= aGrabBag; + for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i ) + { + if( aGrabBag[i].Name == "EffectProperties" ) + aGrabBag[i].Value >>= aEffectProps; + } + if( aEffectProps.getLength() == 0 ) + return; + + OUString sSchemeClr; + sal_uInt32 nRgbClr = 0; + sal_Int32 nAlpha = MAX_PERCENT; + Sequence< PropertyValue > aTransformations; + sax_fastparser::FastAttributeList *aOuterShdwAttrList = mpFS->createAttrList(); + for( sal_Int32 i=0; i < aEffectProps.getLength(); ++i ) + { + if(aEffectProps[i].Name == "outerShdw") + { + uno::Sequence< beans::PropertyValue > aOuterShdwProps; + aEffectProps[0].Value >>= aOuterShdwProps; + for( sal_Int32 j=0; j < aOuterShdwProps.getLength(); ++j ) + { + if( aOuterShdwProps[j].Name == "algn" ) + { + OUString sVal; + aOuterShdwProps[j].Value >>= sVal; + aOuterShdwAttrList->add( XML_algn, OUStringToOString( sVal, RTL_TEXTENCODING_UTF8 ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "blurRad" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_blurRad, OString::number( nVal ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "dir" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_dir, OString::number( nVal ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "dist" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_dist, OString::number( nVal ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "kx" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_kx, OString::number( nVal ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "ky" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_ky, OString::number( nVal ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "rotWithShape" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_rotWithShape, OString::number( nVal ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "sx" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_sx, OString::number( nVal ).getStr() ); + } + else if( aOuterShdwProps[j].Name == "sy" ) + { + sal_Int32 nVal = 0; + aOuterShdwProps[j].Value >>= nVal; + aOuterShdwAttrList->add( XML_sy, OString::number( nVal ).getStr() ); + } + } + } + else if(aEffectProps[i].Name == "ShadowRgbClr") + { + aEffectProps[i].Value >>= nRgbClr; + } + else if(aEffectProps[i].Name == "ShadowRgbClrTransparency") + { + sal_Int32 nTransparency; + aEffectProps[i].Value >>= nTransparency; + // Calculate alpha value (see oox/source/drawingml/color.cxx : getTransparency()) + nAlpha = MAX_PERCENT - ( PER_PERCENT * nTransparency ); + } + else if(aEffectProps[i].Name == "ShadowColorSchemeClr") + { + aEffectProps[i].Value >>= sSchemeClr; + } + else if(aEffectProps[i].Name == "ShadowColorTransformations") + { + aEffectProps[i].Value >>= aTransformations; + } + } + + mpFS->startElementNS(XML_a, XML_effectLst, FSEND); + sax_fastparser::XFastAttributeListRef xAttrList( aOuterShdwAttrList ); + mpFS->startElementNS( XML_a, XML_outerShdw, xAttrList ); + + if( sSchemeClr.isEmpty() ) + WriteColor( nRgbClr, nAlpha ); + else + WriteColor( sSchemeClr, aTransformations ); + + mpFS->endElementNS( XML_a, XML_outerShdw ); + mpFS->endElementNS(XML_a, XML_effectLst); +} + } } diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 28b01ab60fbd..49d1a4bf31e4 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -373,6 +373,7 @@ ShapeExport& ShapeExport::WriteCustomShape( Reference< XShape > xShape ) { WriteFill( rXPropSet ); WriteOutline( rXPropSet ); + WriteShapeEffects( rXPropSet ); } pFS->endElementNS( mnXmlNamespace, XML_spPr ); diff --git a/sw/qa/extras/ooxmlexport/data/shape-effect-preservation.docx b/sw/qa/extras/ooxmlexport/data/shape-effect-preservation.docx Binary files differnew file mode 100644 index 000000000000..aecbd59826d9 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/shape-effect-preservation.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx index 674b496821b8..a6fdc9eb98b4 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx @@ -1029,6 +1029,65 @@ DECLARE_OOXMLEXPORT_TEST(testFdo76979, "fdo76979.docx") assertXPath(pXmlDoc, "//wps:spPr/a:solidFill/a:srgbClr", "val", "FFFFFF"); } +DECLARE_OOXMLEXPORT_TEST(testShapeEffectPreservation, "shape-effect-preservation.docx") +{ + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + if (!pXmlDoc) + return; + + // first shape with outer shadow, rgb color + 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", + "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"); + 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"); + 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", + "dist", "38100"); + 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", + "rotWithShape", "0"); + 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/a:srgbClr", + "val", "000000"); + 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/a:srgbClr/a:alpha", + "val", "40000"); + + // second shape with outer shadow, scheme color + 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", + "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"); + 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"); + 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", + "dist", "203200"); + 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", + "rotWithShape", "0"); + 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/a:schemeClr", + "val", "accent1"); + 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/a:schemeClr/a:lumMod", + "val", "40000"); + 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/a:schemeClr/a:lumOff", + "val", "60000"); + 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/a:schemeClr/a:alpha", + "val", "40000"); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); |