From 4b4f7e17ad5571482111f1574f7e4b313531cfde Mon Sep 17 00:00:00 2001 From: Jacobo Aragunde PĂ©rez Date: Mon, 12 May 2014 19:13:06 +0200 Subject: ooxml: Preserve shape 3d effects: extrusion and contour colors Shapes 3D effects can specify colors for extrusion and contours like in the following example: Colors can be theme-defined or set in RGB and can contain transformations. This patch preserves all the color information using the shape grab bag and modifies an existing unit test to add this check. Change-Id: Ida168affd4ca2135d0bd8f97135dc1cd1e74165a --- include/oox/drawingml/shape3dproperties.hxx | 7 +++- oox/source/drawingml/scene3dcontext.cxx | 5 +++ oox/source/drawingml/shape.cxx | 2 +- oox/source/drawingml/shape3dproperties.cxx | 41 +++++++++++++++++++- oox/source/export/drawingml.cxx | 59 +++++++++++++++++++++++++++++ sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx | 12 ++++++ 6 files changed, 122 insertions(+), 4 deletions(-) diff --git a/include/oox/drawingml/shape3dproperties.hxx b/include/oox/drawingml/shape3dproperties.hxx index e57ac942bf8a..5c3eaa00ead2 100644 --- a/include/oox/drawingml/shape3dproperties.hxx +++ b/include/oox/drawingml/shape3dproperties.hxx @@ -64,6 +64,8 @@ struct Shape3DProperties OptValue< sal_Int32 > mnContourW; OptValue< sal_Int32 > mnShapeZ; OptValue< sal_Int32 > mnMaterial; + Color maExtrusionColor; + Color maContourColor; OptValue< BevelProperties > maTopBevelProperties; OptValue< BevelProperties > maBottomBevelProperties; @@ -79,8 +81,11 @@ struct Shape3DProperties css::uno::Sequence< css::beans::PropertyValue > getCameraAttributes(); css::uno::Sequence< css::beans::PropertyValue > getLightRigAttributes(); - css::uno::Sequence< css::beans::PropertyValue > getShape3DAttributes(); + css::uno::Sequence< css::beans::PropertyValue > getShape3DAttributes( + const GraphicHelper& rGraphicHelper, sal_Int32 rPhClr = API_RGB_TRANSPARENT ); css::uno::Sequence< css::beans::PropertyValue > getBevelAttributes( BevelProperties rProps ); + css::uno::Sequence< css::beans::PropertyValue > getColorAttributes( + const Color& rColor, const GraphicHelper& rGraphicHelper, sal_Int32 rPhClr ); }; diff --git a/oox/source/drawingml/scene3dcontext.cxx b/oox/source/drawingml/scene3dcontext.cxx index ec9204b94a25..c8d9dd5a8386 100644 --- a/oox/source/drawingml/scene3dcontext.cxx +++ b/oox/source/drawingml/scene3dcontext.cxx @@ -104,6 +104,11 @@ ContextHandlerRef Shape3DPropertiesContext::onCreateContext( sal_Int32 aElementT break; } + case A_TOKEN( extrusionClr ): + return new ColorContext( *this, mr3DProperties.maExtrusionColor ); + + case A_TOKEN( contourClr ): + return new ColorContext( *this, mr3DProperties.maContourColor ); } return 0; } diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index da125cfa4ab9..6d138686ff77 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -940,7 +940,7 @@ Reference< XShape > Shape::createAndInsert( // add 3D effects if any Sequence< PropertyValue > aCamera3DEffects = get3DProperties().getCameraAttributes(); Sequence< PropertyValue > aLightRig3DEffects = get3DProperties().getLightRigAttributes(); - Sequence< PropertyValue > aShape3DEffects = get3DProperties().getShape3DAttributes(); + Sequence< PropertyValue > aShape3DEffects = get3DProperties().getShape3DAttributes( rGraphicHelper, nFillPhClr ); if( aCamera3DEffects.getLength() > 0 || aLightRig3DEffects.getLength() > 0 ) { Sequence< PropertyValue > a3DEffectsGrabBag( 3 ); diff --git a/oox/source/drawingml/shape3dproperties.cxx b/oox/source/drawingml/shape3dproperties.cxx index 9bb434ab3718..e3f39b6267a9 100644 --- a/oox/source/drawingml/shape3dproperties.cxx +++ b/oox/source/drawingml/shape3dproperties.cxx @@ -325,9 +325,34 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getBevelAttri return aSeq; } -css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAttributes() +css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getColorAttributes( + const Color& rColor, const GraphicHelper& rGraphicHelper, sal_Int32 rPhClr ) { - css::uno::Sequence aSeq(6); + css::uno::Sequence aSeq(2); + OUString sColorScheme = rColor.getSchemeName(); + if( sColorScheme.isEmpty() ) + { + // RGB color and transparency value + aSeq[0].Name = "rgbClr"; + aSeq[0].Value = css::uno::Any( rColor.getColor( rGraphicHelper, rPhClr ) ); + aSeq[1].Name = "rgbClrTransparency"; + aSeq[1].Value = css::uno::Any( rColor.getTransparency() ); + } + else + { + // scheme color with name and transformations + aSeq[0].Name = "schemeClr"; + aSeq[0].Value = css::uno::Any( sColorScheme ); + aSeq[1].Name = "schemeClrTransformations"; + aSeq[1].Value = css::uno::Any( rColor.getTransformations() ); + } + return aSeq; +} + +css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAttributes( + const GraphicHelper& rGraphicHelper, sal_Int32 rPhClr ) +{ + css::uno::Sequence aSeq(8); sal_Int32 nSize = 0; if( mnExtrusionH.has() ) { @@ -365,6 +390,18 @@ css::uno::Sequence< css::beans::PropertyValue > Shape3DProperties::getShape3DAtt aSeq[nSize].Value = css::uno::Any( getBevelAttributes( maBottomBevelProperties.use() ) ); nSize++; } + if( maExtrusionColor.isUsed() ) + { + aSeq[nSize].Name = "extrusionClr"; + aSeq[nSize].Value = css::uno::Any( getColorAttributes( maExtrusionColor, rGraphicHelper, rPhClr ) ); + nSize++; + } + if( maContourColor.isUsed() ) + { + aSeq[nSize].Name = "contourClr"; + aSeq[nSize].Value = css::uno::Any( getColorAttributes( maContourColor, rGraphicHelper, rPhClr ) ); + nSize++; + } aSeq.realloc( nSize ); return aSeq; } diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 17d22737dce9..99deb828904d 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -2409,6 +2409,7 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet ) return; bool bBevelTPresent = false, bBevelBPresent = false; + Sequence< PropertyValue > aExtrusionColorProps, aContourColorProps; sax_fastparser::FastAttributeList *aBevelTAttrList = mpFS->createAttrList(); sax_fastparser::FastAttributeList *aBevelBAttrList = mpFS->createAttrList(); sax_fastparser::FastAttributeList *aShape3DAttrList = mpFS->createAttrList(); @@ -2432,6 +2433,14 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet ) aShape3DProps[i].Value >>= sVal; aShape3DAttrList->add( XML_prstMaterial, OUStringToOString( sVal, RTL_TEXTENCODING_UTF8 ).getStr() ); } + else if( aShape3DProps[i].Name == "extrusionClr" ) + { + aShape3DProps[i].Value >>= aExtrusionColorProps; + } + else if( aShape3DProps[i].Name == "contourClr" ) + { + aShape3DProps[i].Value >>= aContourColorProps; + } else if( aShape3DProps[i].Name == "bevelT" || aShape3DProps[i].Name == "bevelB" ) { Sequence< PropertyValue > aBevelProps; @@ -2485,6 +2494,56 @@ void DrawingML::WriteShape3DEffects( Reference< XPropertySet > xPropSet ) sax_fastparser::XFastAttributeListRef xBevelAttrList( aBevelBAttrList ); mpFS->singleElementNS( XML_a, XML_bevelB, xBevelAttrList ); } + if( aExtrusionColorProps.getLength() > 0 ) + { + OUString sSchemeClr; + sal_Int32 nColor, nTransparency; + Sequence< PropertyValue > aColorTransformations; + for( sal_Int32 i=0; i < aExtrusionColorProps.getLength(); ++i ) + { + if( aExtrusionColorProps[i].Name == "schemeClr" ) + aExtrusionColorProps[i].Value >>= sSchemeClr; + else if( aExtrusionColorProps[i].Name == "schemeClrTransformations" ) + aExtrusionColorProps[i].Value >>= aColorTransformations; + else if( aExtrusionColorProps[i].Name == "rgbClr" ) + aExtrusionColorProps[i].Value >>= nColor; + else if( aExtrusionColorProps[i].Name == "rgbClrTransparency" ) + aExtrusionColorProps[i].Value >>= nTransparency; + } + mpFS->startElementNS( XML_a, XML_extrusionClr, FSEND ); + + if( sSchemeClr.isEmpty() ) + WriteColor( nColor, MAX_PERCENT - ( PER_PERCENT * nTransparency ) ); + else + WriteColor( sSchemeClr, aColorTransformations ); + + mpFS->endElementNS( XML_a, XML_extrusionClr ); + } + if( aContourColorProps.getLength() > 0 ) + { + OUString sSchemeClr; + sal_Int32 nColor, nTransparency; + Sequence< PropertyValue > aColorTransformations; + for( sal_Int32 i=0; i < aContourColorProps.getLength(); ++i ) + { + if( aContourColorProps[i].Name == "schemeClr" ) + aContourColorProps[i].Value >>= sSchemeClr; + else if( aContourColorProps[i].Name == "schemeClrTransformations" ) + aContourColorProps[i].Value >>= aColorTransformations; + else if( aContourColorProps[i].Name == "rgbClr" ) + aContourColorProps[i].Value >>= nColor; + else if( aContourColorProps[i].Name == "rgbClrTransparency" ) + aContourColorProps[i].Value >>= nTransparency; + } + mpFS->startElementNS( XML_a, XML_contourClr, FSEND ); + + if( sSchemeClr.isEmpty() ) + WriteColor( nColor, MAX_PERCENT - ( PER_PERCENT * nTransparency ) ); + else + WriteColor( sSchemeClr, aContourColorProps ); + + mpFS->endElementNS( XML_a, XML_contourClr ); + } mpFS->endElementNS( XML_a, XML_sp3d ); } diff --git a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx index 3a6782cea8cc..7996d645a011 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlsdrexport.cxx @@ -1214,6 +1214,15 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv 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:sp3d", "prstMaterial", "metal"); + 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:sp3d/a:extrusionClr/a:schemeClr", + "val", "accent5"); + 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:sp3d/a:extrusionClr/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:sp3d/a:extrusionClr/a:schemeClr/a:lumOff", + "val", "60000"); // third shape: colored countour and top and bottom bevel, plastic material assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" @@ -1237,6 +1246,9 @@ DECLARE_OOXMLEXPORT_TEST(testShape3DEffectPreservation, "shape-3d-effect-preserv assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d/a:bevelB", "prst", "relaxedInset"); + assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" + "wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:sp3d/a:contourClr/a:srgbClr", + "val", "3333ff"); // fourth shape: wireframe assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:r/mc:AlternateContent/mc:Choice/w:drawing/" -- cgit