diff options
author | Vinaya Mandke <vinaya.mandke@synerzip.com> | 2014-01-29 12:40:01 +0530 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2014-02-12 02:40:06 +0100 |
commit | a5f0344b410e2fbf1e80b18fa6d5094f44cc06bc (patch) | |
tree | fecf43e544951226797c92d6ba70f9454397c652 | |
parent | f0d232f7b78edc3a0acff6d2beee97ff8bb2bd94 (diff) |
fdo#74115 Fix for DOCX GradientFill for Chart Wall
Fixed import and export for chart wall Gradient Fill in DOCX
Added UT for the same.
Conflicts:
chart2/qa/extras/chart2export.cxx
Change-Id: Ie6caa2b238aeb70f7225145da8c5c78003e73002
-rw-r--r-- | chart2/qa/extras/chart2export.cxx | 13 | ||||
-rw-r--r-- | chart2/qa/extras/data/docx/fdo74115_WallGradientFill.docx | bin | 0 -> 17942 bytes | |||
-rw-r--r-- | include/oox/export/chartexport.hxx | 3 | ||||
-rw-r--r-- | include/oox/export/drawingml.hxx | 2 | ||||
-rw-r--r-- | oox/source/drawingml/chart/objectformatter.cxx | 2 | ||||
-rw-r--r-- | oox/source/export/chartexport.cxx | 61 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 178 |
7 files changed, 172 insertions, 87 deletions
diff --git a/chart2/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx index 399c0bbf9f8b..d51bd1c96d62 100644 --- a/chart2/qa/extras/chart2export.cxx +++ b/chart2/qa/extras/chart2export.cxx @@ -43,6 +43,7 @@ public: void testUpDownBars(); void testDoughnutChart(); void testDisplayUnits(); + void testFdo74115WallGradientFill(); CPPUNIT_TEST_SUITE(Chart2ExportTest); CPPUNIT_TEST(test); @@ -58,6 +59,7 @@ public: CPPUNIT_TEST(testUpDownBars); CPPUNIT_TEST(testDoughnutChart); CPPUNIT_TEST(testDisplayUnits); + CPPUNIT_TEST(testFdo74115WallGradientFill); CPPUNIT_TEST_SUITE_END(); protected: @@ -162,6 +164,7 @@ xmlNodeSetPtr Chart2ExportTest::getXPathNode(xmlDocPtr pXmlDoc, const OString& r xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml")); xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart")); + xmlXPathRegisterNs(pXmlXpathCtx, BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main")); xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(rXPath.getStr()), pXmlXpathCtx); return pXmlXpathObj->nodesetval; } @@ -540,9 +543,19 @@ void Chart2ExportTest::testDisplayUnits() load("/chart2/qa/extras/data/docx/", "DisplayUnits.docx"); xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); CPPUNIT_ASSERT(pXmlDoc); + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:valAx/c:dispUnits/c:builtInUnit", "val", "billions"); } +void Chart2ExportTest::testFdo74115WallGradientFill() +{ + load("/chart2/qa/extras/data/docx/", "fdo74115_WallGradientFill.docx"); + xmlDocPtr pXmlDoc = parseExport("word/charts/chart", "Office Open XML Text"); + CPPUNIT_ASSERT(pXmlDoc); + + assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:plotArea/c:spPr/a:gradFill"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/chart2/qa/extras/data/docx/fdo74115_WallGradientFill.docx b/chart2/qa/extras/data/docx/fdo74115_WallGradientFill.docx Binary files differnew file mode 100644 index 000000000000..e10334bd9a90 --- /dev/null +++ b/chart2/qa/extras/data/docx/fdo74115_WallGradientFill.docx diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx index 729e9ef28a21..c9c13ba40ff7 100644 --- a/include/oox/export/chartexport.hxx +++ b/include/oox/export/chartexport.hxx @@ -120,6 +120,9 @@ private: void exportTitle( com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); void exportPlotArea( ); + void exportPlotAreaShapeProps( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet ); + void exportFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet ); + void exportGradientFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > xPropSet ); void exportDataTable( ); void exportAreaChart( com::sun::star::uno::Reference< com::sun::star::chart2::XChartType > xChartType ); diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 84ac60607363..8b963f70ac52 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -130,6 +130,8 @@ public: void WriteSolidFill( OUString sSchemeName, ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aTransformations ); void WriteSolidFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); void WriteGradientFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet ); + void WriteGradientFill( ::com::sun::star::awt::Gradient rGradient ); + void WriteGrabBagGradientFill( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aGradientStops, ::com::sun::star::awt::Gradient rGradient); void WriteBlipFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, OUString sURLPropName, sal_Int32 nXmlNamespace ); void WriteBlipFill( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > rXPropSet, OUString sURLPropName ); void WriteSrcRect( ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >, const OUString& ); diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx index 29cc07b6e9ec..a840381df2cc 100644 --- a/oox/source/drawingml/chart/objectformatter.cxx +++ b/oox/source/drawingml/chart/objectformatter.cxx @@ -467,7 +467,7 @@ static const sal_Int32 spnCommonPropIds[] = { PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, - PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_FillGradientName, + PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_INVALID, PROP_FillGradientName, PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint }; diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index ed5ea8bc9e46..4d8d931a4541 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -25,6 +25,7 @@ #include <cstdio> +#include <com/sun/star/awt/Gradient.hpp> #include <com/sun/star/chart/XChartDocument.hpp> #include <com/sun/star/chart/ChartLegendPosition.hpp> #include <com/sun/star/chart/XTwoAxisXSupplier.hpp> @@ -1124,19 +1125,77 @@ void ChartExport::exportPlotArea( ) exportDataTable(); // shape properties + /* + * Export the Plot area Shape Properties + * eg: Fill and Outline + */ Reference< ::com::sun::star::chart::X3DDisplay > xWallFloorSupplier( mxDiagram, uno::UNO_QUERY ); if( xWallFloorSupplier.is() ) { Reference< beans::XPropertySet > xWallPropSet( xWallFloorSupplier->getWall(), uno::UNO_QUERY ); if( xWallPropSet.is() ) { - exportShapeProps( xWallPropSet ); + exportPlotAreaShapeProps( xWallPropSet ); } } + pFS->endElement( FSNS( XML_c, XML_plotArea ) ); } +void ChartExport::exportPlotAreaShapeProps( Reference< XPropertySet > xPropSet ) +{ + FSHelperPtr pFS = GetFS(); + pFS->startElement( FSNS( XML_c, XML_spPr ), + FSEND ); + + exportFill( xPropSet ); + WriteOutline( xPropSet ); + + pFS->endElement( FSNS( XML_c, XML_spPr ) ); +} + +void ChartExport::exportFill( Reference< XPropertySet > xPropSet ) +{ + if ( !GetProperty( xPropSet, "FillStyle" ) ) + return; + FillStyle aFillStyle( FillStyle_NONE ); + xPropSet->getPropertyValue( "FillStyle" ) >>= aFillStyle; + switch( aFillStyle ) + { + case FillStyle_GRADIENT : + exportGradientFill( xPropSet ); + default: + WriteFill( xPropSet ); + } +} + +void ChartExport::exportGradientFill( Reference< XPropertySet > xPropSet ) +{ + if( xPropSet.is() ) + { + OUString sFillGradientName; + xPropSet->getPropertyValue("FillGradientName") >>= sFillGradientName; + + awt::Gradient aGradient; + uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY ); + try + { + uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY ); + uno::Any rValue = xGradient->getByName( sFillGradientName ); + if( (rValue >>= aGradient) ) + { + WriteGradientFill( aGradient ); + } + } + catch( const uno::Exception & rEx ) + { + DBG_WARNING( "Gradient Property not Found; ChartExport::exportPlotAreaGradientFill" ); + } + + } +} + void ChartExport::exportDataTable( ) { FSHelperPtr pFS = GetFS(); diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 0f95e7018c62..1584356fc767 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -338,102 +338,110 @@ void DrawingML::WriteGradientFill( Reference< XPropertySet > rXPropSet ) aGrabBag[i].Value >>= aOriginalGradient; } - mpFS->startElementNS( XML_a, XML_gradFill, FSEND ); - // check if an ooxml gradient had been imported and if the user has modified it if( aGradientStops.hasElements() && EqualGradients( aOriginalGradient, aGradient ) ) { - // write back the original gradient - mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); + WriteGrabBagGradientFill(aGradientStops, aGradient); + } + else + WriteGradientFill(aGradient); + } +} +void DrawingML::WriteGrabBagGradientFill( Sequence< PropertyValue > aGradientStops, awt::Gradient rGradient ) +{ + mpFS->startElementNS( XML_a, XML_gradFill, FSEND ); + // write back the original gradient + mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); - // get original stops and write them - for( sal_Int32 i=0; i < aGradientStops.getLength(); ++i ) - { - Sequence< PropertyValue > aGradientStop; - aGradientStops[i].Value >>= aGradientStop; - - // get values - OUString sSchemeClr; - double nPos = 0; - sal_Int16 nTransparency = 0; - sal_Int32 nRgbClr = 0; - Sequence< PropertyValue > aTransformations; - for( sal_Int32 j=0; j < aGradientStop.getLength(); ++j ) - if( aGradientStop[j].Name == "SchemeClr" ) - aGradientStop[j].Value >>= sSchemeClr; - else if( aGradientStop[j].Name == "RgbClr" ) - aGradientStop[j].Value >>= nRgbClr; - else if( aGradientStop[j].Name == "Pos" ) - aGradientStop[j].Value >>= nPos; - else if( aGradientStop[j].Name == "Transparency" ) - aGradientStop[j].Value >>= nTransparency; - else if( aGradientStop[j].Name == "Transformations" ) - aGradientStop[j].Value >>= aTransformations; - - // write stop - mpFS->startElementNS( XML_a, XML_gs, - XML_pos, OString::number( nPos * 100000.0 ).getStr(), - FSEND ); - if( sSchemeClr.isEmpty() ) - { - // Calculate alpha value (see oox/source/drawingml/color.cxx : getTransparency()) - sal_Int32 nAlpha = (MAX_PERCENT - ( PER_PERCENT * nTransparency ) ); - WriteColor( nRgbClr, nAlpha ); - } - else - WriteColor( sSchemeClr, aTransformations ); - mpFS->endElementNS( XML_a, XML_gs ); - } - mpFS->endElementNS( XML_a, XML_gsLst ); + // get original stops and write them + for( sal_Int32 i=0; i < aGradientStops.getLength(); ++i ) + { + Sequence< PropertyValue > aGradientStop; + aGradientStops[i].Value >>= aGradientStop; - mpFS->singleElementNS( XML_a, XML_lin, - XML_ang, I32S( ( ( ( 3600 - aGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), - FSEND ); + // get values + OUString sSchemeClr; + double nPos = 0; + sal_Int16 nTransparency = 0; + sal_Int32 nRgbClr = 0; + Sequence< PropertyValue > aTransformations; + for( sal_Int32 j=0; j < aGradientStop.getLength(); ++j ) + if( aGradientStop[j].Name == "SchemeClr" ) + aGradientStop[j].Value >>= sSchemeClr; + else if( aGradientStop[j].Name == "RgbClr" ) + aGradientStop[j].Value >>= nRgbClr; + else if( aGradientStop[j].Name == "Pos" ) + aGradientStop[j].Value >>= nPos; + else if( aGradientStop[j].Name == "Transparency" ) + aGradientStop[j].Value >>= nTransparency; + else if( aGradientStop[j].Name == "Transformations" ) + aGradientStop[j].Value >>= aTransformations; + + // write stop + mpFS->startElementNS( XML_a, XML_gs, + XML_pos, OString::number( nPos * 100000.0 ).getStr(), + FSEND ); + if( sSchemeClr.isEmpty() ) + { + // Calculate alpha value (see oox/source/drawingml/color.cxx : getTransparency()) + sal_Int32 nAlpha = (MAX_PERCENT - ( PER_PERCENT * nTransparency ) ); + WriteColor( nRgbClr, nAlpha ); } else - switch( aGradient.Style ) { - default: - case GradientStyle_LINEAR: - mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); - WriteGradientStop( 0, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) ); - WriteGradientStop( 100, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) ); - mpFS->endElementNS( XML_a, XML_gsLst ); - mpFS->singleElementNS( XML_a, XML_lin, - XML_ang, I32S( ( ( ( 3600 - aGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), - FSEND ); - break; + WriteColor( sSchemeClr, aTransformations ); + mpFS->endElementNS( XML_a, XML_gs ); + } + mpFS->endElementNS( XML_a, XML_gsLst ); - case GradientStyle_AXIAL: - mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); - WriteGradientStop( 0, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) ); - WriteGradientStop( 50, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) ); - WriteGradientStop( 100, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) ); - mpFS->endElementNS( XML_a, XML_gsLst ); - mpFS->singleElementNS( XML_a, XML_lin, - XML_ang, I32S( ( ( ( 3600 - aGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), - FSEND ); - break; + mpFS->singleElementNS( XML_a, XML_lin, + XML_ang, I32S( ( ( ( 3600 - rGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), + FSEND ); + mpFS->endElementNS( XML_a, XML_gradFill ); +} - /* I don't see how to apply transformation to gradients, so - * elliptical will end as radial and square as - * rectangular. also position offsets are not applied */ - case GradientStyle_RADIAL: - case GradientStyle_ELLIPTICAL: - case GradientStyle_RECT: - case GradientStyle_SQUARE: - mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); - WriteGradientStop( 0, ColorWithIntensity( aGradient.EndColor, aGradient.EndIntensity ) ); - WriteGradientStop( 100, ColorWithIntensity( aGradient.StartColor, aGradient.StartIntensity ) ); - mpFS->endElementNS( XML_a, XML_gsLst ); - mpFS->singleElementNS( XML_a, XML_path, - XML_path, ( aGradient.Style == awt::GradientStyle_RADIAL || aGradient.Style == awt::GradientStyle_ELLIPTICAL ) ? "circle" : "rect", - FSEND ); - break; - } +void DrawingML::WriteGradientFill( awt::Gradient rGradient ) +{ + mpFS->startElementNS( XML_a, XML_gradFill, FSEND ); + switch( rGradient.Style ) { + default: + case GradientStyle_LINEAR: + mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); + WriteGradientStop( 0, ColorWithIntensity( rGradient.StartColor, rGradient.StartIntensity ) ); + WriteGradientStop( 100, ColorWithIntensity( rGradient.EndColor, rGradient.EndIntensity ) ); + mpFS->endElementNS( XML_a, XML_gsLst ); + mpFS->singleElementNS( XML_a, XML_lin, + XML_ang, I32S( ( ( ( 3600 - rGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), + FSEND ); + break; - mpFS->endElementNS( XML_a, XML_gradFill ); - } + case GradientStyle_AXIAL: + mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); + WriteGradientStop( 0, ColorWithIntensity( rGradient.EndColor, rGradient.EndIntensity ) ); + WriteGradientStop( 50, ColorWithIntensity( rGradient.StartColor, rGradient.StartIntensity ) ); + WriteGradientStop( 100, ColorWithIntensity( rGradient.EndColor, rGradient.EndIntensity ) ); + mpFS->endElementNS( XML_a, XML_gsLst ); + mpFS->singleElementNS( XML_a, XML_lin, + XML_ang, I32S( ( ( ( 3600 - rGradient.Angle + 900 ) * 6000 ) % 21600000 ) ), + FSEND ); + break; + /* I don't see how to apply transformation to gradients, so + * elliptical will end as radial and square as + * rectangular. also position offsets are not applied */ + case GradientStyle_RADIAL: + case GradientStyle_ELLIPTICAL: + case GradientStyle_RECT: + case GradientStyle_SQUARE: + mpFS->startElementNS( XML_a, XML_gsLst, FSEND ); + WriteGradientStop( 0, ColorWithIntensity( rGradient.EndColor, rGradient.EndIntensity ) ); + WriteGradientStop( 100, ColorWithIntensity( rGradient.StartColor, rGradient.StartIntensity ) ); + mpFS->endElementNS( XML_a, XML_gsLst ); + mpFS->singleElementNS( XML_a, XML_path, + XML_path, ( rGradient.Style == awt::GradientStyle_RADIAL || rGradient.Style == awt::GradientStyle_ELLIPTICAL ) ? "circle" : "rect", + FSEND ); + break; + } + mpFS->endElementNS( XML_a, XML_gradFill ); } void DrawingML::WriteLineArrow( Reference< XPropertySet > rXPropSet, sal_Bool bLineStart ) |