From 31919b8909fa7b34412dd52c3d4dff17bc5b6fab Mon Sep 17 00:00:00 2001 From: Tamás Zolnai Date: Fri, 22 Sep 2017 01:17:14 +0200 Subject: tdf#112552: Shape's gray background is lost after saving to PPTX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I30f371ad301eede82ddcece4d91ffcd32e164115 Reviewed-on: https://gerrit.libreoffice.org/42598 Tested-by: Jenkins Reviewed-by: Tamás Zolnai --- include/oox/export/drawingml.hxx | 7 ++- include/svx/EnhancedCustomShape2d.hxx | 4 +- oox/source/export/drawingml.cxx | 89 ++++++++++++++++------------------ oox/source/export/shapes.cxx | 2 +- sd/qa/unit/data/odp/tdf112552.odp | Bin 0 -> 11331 bytes sd/qa/unit/export-tests-ooxml2.cxx | 17 +++++++ 6 files changed, 68 insertions(+), 51 deletions(-) create mode 100755 sd/qa/unit/data/odp/tdf112552.odp diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index c33bb40f4306..ded3f4e488aa 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -45,6 +45,7 @@ #endif class Graphic; +class SdrObjCustomShape; namespace com { namespace sun { namespace star { namespace awt { @@ -58,6 +59,8 @@ namespace beans { } namespace drawing { class XShape; + struct EnhancedCustomShapeParameterPair; + struct EnhancedCustomShapeParameter; } namespace style { struct LineSpacing; @@ -212,7 +215,9 @@ public: void WritePresetShape( const char* pShape , std::vector< std::pair> & rAvList ); void WritePresetShape( const char* pShape ); void WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool bPredefinedHandlesUsed, sal_Int32 nAdjustmentsWhichNeedsToBeConverted, const css::beans::PropertyValue& rProp ); - bool WriteCustomGeometry( const css::uno::Reference& rXShape ); + bool WriteCustomGeometry( const css::uno::Reference& rXShape, const SdrObjCustomShape* pShape ); + void WriteCustomGeometryPoint(const css::drawing::EnhancedCustomShapeParameterPair& rParamPair, const SdrObjCustomShape* pShape); + static sal_Int32 GetCustomGeometryPointValue(const css::drawing::EnhancedCustomShapeParameter& rParam, const SdrObjCustomShape* pShape); void WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon ); void WriteFill( const css::uno::Reference< css::beans::XPropertySet >& xPropSet ); void WriteShapeStyle( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet ); diff --git a/include/svx/EnhancedCustomShape2d.hxx b/include/svx/EnhancedCustomShape2d.hxx index 86ec0f082628..df6603a46183 100644 --- a/include/svx/EnhancedCustomShape2d.hxx +++ b/include/svx/EnhancedCustomShape2d.hxx @@ -125,8 +125,6 @@ class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet SAL_DLLPRIVATE Color GetColorData( const Color& rFillColor, sal_uInt32 nIndex, double dBrightness ) const; SAL_DLLPRIVATE void AdaptObjColor(SdrPathObj& rObj, const SfxItemSet& rCustomShapeSet, sal_uInt32& nColorIndex, sal_uInt32 nColorCount); - SAL_DLLPRIVATE void GetParameter( double& rParameterReturnValue, const css::drawing::EnhancedCustomShapeParameter&, - const bool bReplaceGeoWidth, const bool bReplaceGeoHeight ) const; SAL_DLLPRIVATE Point GetPoint( const css::drawing::EnhancedCustomShapeParameterPair&, const bool bScale = true, const bool bReplaceGeoSize = false ) const; @@ -188,6 +186,8 @@ class SVX_DLLPUBLIC EnhancedCustomShape2d : public SfxItemSet SAL_DLLPRIVATE double GetEnumFunc( const EnhancedCustomShape::ExpressionFunct eVal ) const; + void GetParameter( double& rParameterReturnValue, const css::drawing::EnhancedCustomShapeParameter&, + const bool bReplaceGeoWidth, const bool bReplaceGeoHeight ) const; SAL_DLLPRIVATE double GetAdjustValueAsDouble( const sal_Int32 nIndex ) const; SAL_DLLPRIVATE double GetEquationValueAsDouble( const sal_Int32 nIndex ) const; diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 1ce02a7e2b53..198ac917bb92 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -95,6 +95,7 @@ #include #include #include +#include #include using namespace ::css; @@ -2498,7 +2499,7 @@ void DrawingML::WritePresetShape( const char* pShape, MSO_SPT eShapeType, bool b mpFS->endElementNS( XML_a, XML_prstGeom ); } -bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape ) +bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape, const SdrObjCustomShape* pShape ) { uno::Reference< beans::XPropertySet > aXPropSet; uno::Any aAny( rXShape->queryInterface(cppu::UnoType::get())); @@ -2598,15 +2599,16 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape ) for ( int j = 0; j < aPairs.getLength(); ++j ) { - sal_Int32 nCandidate(0); - if ((aPairs[j].First.Value >>= nCandidate) && nCandidate < nXMin) - nXMin = nCandidate; - if ((aPairs[j].Second.Value >>= nCandidate) && nCandidate < nYMin) - nYMin = nCandidate; - if ((aPairs[j].First.Value >>= nCandidate) && nCandidate > nXMax) - nXMax = nCandidate; - if ((aPairs[j].Second.Value >>= nCandidate) && nCandidate > nYMax) - nYMax = nCandidate; + sal_Int32 nX = GetCustomGeometryPointValue(aPairs[j].First, pShape); + sal_Int32 nY = GetCustomGeometryPointValue(aPairs[j].Second, pShape); + if (nX < nXMin) + nXMin = nX; + if (nY < nYMin) + nYMin = nY; + if (nX > nXMax) + nXMax = nX; + if (nY > nYMax) + nYMax = nY; } mpFS->startElementNS( XML_a, XML_path, XML_w, I64S( nXMax - nXMin ), @@ -2629,16 +2631,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape ) case drawing::EnhancedCustomShapeSegmentCommand::MOVETO : { mpFS->startElementNS( XML_a, XML_moveTo, FSEND ); - - sal_Int32 nX(0), nY(0); - aPairs[nPairIndex].First.Value >>= nX; - aPairs[nPairIndex].Second.Value >>= nY; - - mpFS->singleElementNS( XML_a, XML_pt, - XML_x, I64S(nX), - XML_y, I64S(nY), - FSEND ); - + WriteCustomGeometryPoint(aPairs[nPairIndex], pShape); mpFS->endElementNS( XML_a, XML_moveTo ); nPairIndex++; break; @@ -2646,15 +2639,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape ) case drawing::EnhancedCustomShapeSegmentCommand::LINETO : { mpFS->startElementNS( XML_a, XML_lnTo, FSEND ); - - sal_Int32 nX(0), nY(0); - aPairs[nPairIndex].First.Value >>= nX; - aPairs[nPairIndex].Second.Value >>= nY; - - mpFS->singleElementNS( XML_a, XML_pt, - XML_x, I64S(nX), - XML_y, I64S(nY), - FSEND ); + WriteCustomGeometryPoint(aPairs[nPairIndex], pShape); mpFS->endElementNS( XML_a, XML_lnTo ); nPairIndex++; break; @@ -2664,15 +2649,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape ) mpFS->startElementNS( XML_a, XML_cubicBezTo, FSEND ); for( sal_uInt8 l = 0; l <= 2; ++l ) { - sal_Int32 nX(0), nY(0); - aPairs[nPairIndex+l].First.Value >>= nX; - aPairs[nPairIndex+l].Second.Value >>= nY; - - mpFS->singleElementNS( XML_a, XML_pt, - XML_x, I64S( nX ), - XML_y, I64S( nY ), - FSEND ); - + WriteCustomGeometryPoint(aPairs[nPairIndex+l], pShape); } mpFS->endElementNS( XML_a, XML_cubicBezTo ); nPairIndex += 3; @@ -2703,15 +2680,7 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape ) mpFS->startElementNS( XML_a, XML_quadBezTo, FSEND ); for( sal_uInt8 l = 0; l < 2; ++l ) { - sal_Int32 nX(0), nY(0); - aPairs[nPairIndex+l].First.Value >>= nX; - aPairs[nPairIndex+l].Second.Value >>= nY; - - mpFS->singleElementNS( XML_a, XML_pt, - XML_x, I64S( nX ), - XML_y, I64S( nY ), - FSEND ); - + WriteCustomGeometryPoint(aPairs[nPairIndex+l], pShape); } mpFS->endElementNS( XML_a, XML_quadBezTo ); nPairIndex += 2; @@ -2738,6 +2707,32 @@ bool DrawingML::WriteCustomGeometry( const Reference< XShape >& rXShape ) return false; } +void DrawingML::WriteCustomGeometryPoint(const drawing::EnhancedCustomShapeParameterPair& rParamPair, const SdrObjCustomShape* pShape) +{ + sal_Int32 nX = GetCustomGeometryPointValue(rParamPair.First, pShape); + sal_Int32 nY = GetCustomGeometryPointValue(rParamPair.Second, pShape); + + mpFS->singleElementNS( XML_a, XML_pt, + XML_x, OString::number(nX).getStr(), + XML_y, OString::number(nY).getStr(), + FSEND ); +} + +sal_Int32 DrawingML::GetCustomGeometryPointValue(const css::drawing::EnhancedCustomShapeParameter& rParam, const SdrObjCustomShape* pShape) +{ + sal_Int32 nValue = 0; + if(pShape) + { + const EnhancedCustomShape2d aCustoShape2d (const_cast(pShape)); + double fValue = 0.0; + aCustoShape2d.GetParameter(fValue, rParam, false, false); + nValue = std::lround(fValue); + } + else + rParam.Value >>= nValue; + return nValue; +} + void DrawingML::WritePolyPolygon( const tools::PolyPolygon& rPolyPolygon ) { // In case of Writer, the parent element is , and there the diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 955f15894dfa..b3d42048ec6d 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -864,7 +864,7 @@ ShapeExport& ShapeExport::WriteCustomShape( const Reference< XShape >& xShape ) else if (bCustGeom) { WriteShapeTransformation( xShape, XML_a, bFlipH, bFlipV ); - bool bSuccess = WriteCustomGeometry( xShape ); + bool bSuccess = WriteCustomGeometry( xShape, pShape ); if (!bSuccess) WritePresetShape( sPresetShape ); } diff --git a/sd/qa/unit/data/odp/tdf112552.odp b/sd/qa/unit/data/odp/tdf112552.odp new file mode 100755 index 000000000000..df4afb76b14a Binary files /dev/null and b/sd/qa/unit/data/odp/tdf112552.odp differ diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx index 72d0cd04306c..512a4dc32b73 100644 --- a/sd/qa/unit/export-tests-ooxml2.cxx +++ b/sd/qa/unit/export-tests-ooxml2.cxx @@ -109,6 +109,7 @@ public: void testTdf112280(); void testTdf112088(); void testTdf112333(); + void testTdf112552(); CPPUNIT_TEST_SUITE(SdOOXMLExportTest2); @@ -145,6 +146,7 @@ public: CPPUNIT_TEST(testTdf112280); CPPUNIT_TEST(testTdf112088); CPPUNIT_TEST(testTdf112333); + CPPUNIT_TEST(testTdf112552); CPPUNIT_TEST_SUITE_END(); @@ -1098,6 +1100,21 @@ void SdOOXMLExportTest2::testTdf112333() CPPUNIT_ASSERT_EQUAL(OUString("fillcolor"), sAttributeName); } +void SdOOXMLExportTest2::testTdf112552() +{ + // Background fill was not displayed, but it was because of the wrong geometry + ::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/odp/tdf112552.odp"), ODP); + utl::TempFile tempFile; + xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile); + + xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:custGeom/a:pathLst/a:path", "w", "21600"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:custGeom/a:pathLst/a:path", "h", "21600"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:custGeom/a:pathLst/a:path/a:lnTo[1]/a:pt", "x", "21600"); + assertXPath(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp/p:spPr/a:custGeom/a:pathLst/a:path/a:lnTo[1]/a:pt", "y", "0"); + xDocShRef->DoClose(); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); -- cgit