summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/oox/drawingml/effectproperties.hxx7
-rw-r--r--include/oox/export/drawingml.hxx1
-rw-r--r--oox/source/drawingml/effectproperties.cxx30
-rw-r--r--oox/source/drawingml/effectpropertiescontext.cxx29
-rw-r--r--oox/source/drawingml/shape.cxx27
-rw-r--r--oox/source/export/drawingml.cxx118
-rw-r--r--oox/source/export/shapes.cxx1
-rw-r--r--sw/qa/extras/ooxmlexport/data/shape-effect-preservation.docxbin0 -> 17276 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx59
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
new file mode 100644
index 000000000000..aecbd59826d9
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/shape-effect-preservation.docx
Binary files differ
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();