From bf033461c5cb0053253f410da7f17dd2e12771c3 Mon Sep 17 00:00:00 2001 From: EricSeynaeve Date: Thu, 28 Feb 2013 23:07:09 +0100 Subject: fdo#61135 stepped lines graph: handle ods files The boilerplate code for drawing the 4 types of stepped is in place (as described in ODF1.3, https://tools.oasis-open.org/issues/browse/OFFICE-3662). We can also read the current attribute values used in Gnumeric. These values are converted to ODF1.3 during save. Change-Id: I0f04a779de4b65326ed7ce6de56191f11b51c596 --- .../chartapiwrapper/WrappedSplineProperties.cxx | 72 +++++++++-- chart2/source/view/charttypes/AreaChart.cxx | 143 ++++++++++++++++++++- chart2/source/view/charttypes/AreaChart.hxx | 4 + 3 files changed, 206 insertions(+), 13 deletions(-) (limited to 'chart2') diff --git a/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx b/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx index 53dff54d906a..6f9d57f05860 100644 --- a/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx +++ b/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx @@ -231,12 +231,29 @@ Any WrappedSplineTypeProperty::convertInnerToOuterValue( const Any& rInnerValue rInnerValue >>= aInnerValue; sal_Int32 nOuterValue; - if( chart2::CurveStyle_CUBIC_SPLINES == aInnerValue ) - nOuterValue = 1; - else if( chart2::CurveStyle_B_SPLINES == aInnerValue ) - nOuterValue = 2; - else - nOuterValue = 0; + switch (aInnerValue) + { + case chart2::CurveStyle_CUBIC_SPLINES: + nOuterValue = 1; + break; + case chart2::CurveStyle_B_SPLINES: + nOuterValue = 2; + break; + case chart2::CurveStyle_STEP_START: + nOuterValue = 3; + break; + case chart2::CurveStyle_STEP_END: + nOuterValue = 4; + break; + case chart2::CurveStyle_STEP_CENTER_X: + nOuterValue = 5; + break; + case chart2::CurveStyle_STEP_CENTER_Y: + nOuterValue = 6; + break; + default: + nOuterValue = 0; + } return uno::makeAny(nOuterValue); } @@ -247,12 +264,43 @@ Any WrappedSplineTypeProperty::convertOuterToInnerValue( const Any& rOuterValue chart2::CurveStyle aInnerValue; - if(1==nOuterValue) - aInnerValue = chart2::CurveStyle_CUBIC_SPLINES; - else if(2==nOuterValue) - aInnerValue = chart2::CurveStyle_B_SPLINES; - else - aInnerValue = chart2::CurveStyle_LINES; + switch (nOuterValue) + { + case 1: + aInnerValue = chart2::CurveStyle_CUBIC_SPLINES; + break; + case 2: + aInnerValue = chart2::CurveStyle_B_SPLINES; + break; + case 3: + aInnerValue = chart2::CurveStyle_STEP_START; + break; + case 4: + aInnerValue = chart2::CurveStyle_STEP_END; + break; + case 5: + aInnerValue = chart2::CurveStyle_STEP_CENTER_X; + break; + case 6: + aInnerValue = chart2::CurveStyle_STEP_CENTER_Y; + break; + // map the pre-ODF1.3 Gnumeric values to ODF1.3 + case 7: + aInnerValue = chart2::CurveStyle_STEP_START; + break; + case 8: + aInnerValue = chart2::CurveStyle_STEP_END; + break; + case 9: + aInnerValue = chart2::CurveStyle_STEP_CENTER_X; + break; + case 10: + aInnerValue = chart2::CurveStyle_STEP_CENTER_Y; + break; + default: + SAL_WARN_IF(chart2::CurveStyle_LINES != 0, "chart2", "Unknown line style"); + aInnerValue = chart2::CurveStyle_LINES; + } return uno::makeAny(aInnerValue); } diff --git a/chart2/source/view/charttypes/AreaChart.cxx b/chart2/source/view/charttypes/AreaChart.cxx index a9e207c628d8..03f13b17db62 100644 --- a/chart2/source/view/charttypes/AreaChart.cxx +++ b/chart2/source/view/charttypes/AreaChart.cxx @@ -287,6 +287,135 @@ void lcl_removeDuplicatePoints( drawing::PolyPolygonShape3D& rPolyPoly, Plotting rPolyPoly=aTmp; } +bool AreaChart::create_stepped_line( drawing::PolyPolygonShape3D aStartPoly, chart2::CurveStyle eCurveStyle, PlottingPositionHelper* pPosHelper, drawing::PolyPolygonShape3D &aPoly ) +{ + drawing::PolyPolygonShape3D aSteppedPoly; + + aSteppedPoly.SequenceX.realloc(0); + aSteppedPoly.SequenceY.realloc(0); + aSteppedPoly.SequenceZ.realloc(0); + + sal_uInt32 nOuterCount = aStartPoly.SequenceX.getLength(); + if ( !nOuterCount ) + return false; + + aSteppedPoly.SequenceX.realloc(nOuterCount); + aSteppedPoly.SequenceY.realloc(nOuterCount); + aSteppedPoly.SequenceZ.realloc(nOuterCount); + for( sal_uInt32 nOuter = 0; nOuter < nOuterCount; ++nOuter ) + { + if( aStartPoly.SequenceX[nOuter].getLength() <= 1 ) + continue; //we need at least two points + + sal_uInt32 nMaxIndexPoints = aStartPoly.SequenceX[nOuter].getLength()-1; // is >1 + sal_uInt32 nNewIndexPoints = 0; + if ( CurveStyle_STEP_START==eCurveStyle || CurveStyle_STEP_END==eCurveStyle) + nNewIndexPoints = nMaxIndexPoints * 2 + 1; + else + nNewIndexPoints = nMaxIndexPoints * 3 + 1; + + const double* pOldX = aStartPoly.SequenceX[nOuter].getConstArray(); + const double* pOldY = aStartPoly.SequenceY[nOuter].getConstArray(); + const double* pOldZ = aStartPoly.SequenceZ[nOuter].getConstArray(); + + aSteppedPoly.SequenceX[nOuter].realloc( nNewIndexPoints ); + aSteppedPoly.SequenceY[nOuter].realloc( nNewIndexPoints ); + aSteppedPoly.SequenceZ[nOuter].realloc( nNewIndexPoints ); + + double* pNewX = aSteppedPoly.SequenceX[nOuter].getArray(); + double* pNewY = aSteppedPoly.SequenceY[nOuter].getArray(); + double* pNewZ = aSteppedPoly.SequenceZ[nOuter].getArray(); + + pNewX[0] = pOldX[0]; + pNewY[0] = pOldY[0]; + pNewZ[0] = pOldZ[0]; + for( sal_uInt32 oi = 0; oi < nMaxIndexPoints; oi++ ) + { + switch ( eCurveStyle ) + { + case CurveStyle_STEP_START: + /** O + | + | + | + O-----+ + */ + // create the intermediate point + pNewX[1+oi*2] = pOldX[oi+1]; + pNewY[1+oi*2] = pOldY[oi]; + pNewZ[1+oi*2] = pOldZ[oi]; + // and now the normal one + pNewX[1+oi*2+1] = pOldX[oi+1]; + pNewY[1+oi*2+1] = pOldY[oi+1]; + pNewZ[1+oi*2+1] = pOldZ[oi+1]; + break; + case CurveStyle_STEP_END: + /** +------O + | + | + | + O + */ + // create the intermediate point + pNewX[1+oi*2] = pOldX[oi]; + pNewY[1+oi*2] = pOldY[oi+1]; + pNewZ[1+oi*2] = pOldZ[oi]; + // and now the normal one + pNewX[1+oi*2+1] = pOldX[oi+1]; + pNewY[1+oi*2+1] = pOldY[oi+1]; + pNewZ[1+oi*2+1] = pOldZ[oi+1]; + break; + case CurveStyle_STEP_CENTER_X: + /** +--O + | + | + | + O--+ + */ + // create the first intermediate point + pNewX[1+oi*3] = (pOldX[oi]+pOldX[oi+1])/2; + pNewY[1+oi*3] = pOldY[oi]; + pNewZ[1+oi*3] = pOldZ[oi]; + // create the second intermediate point + pNewX[1+oi*3+1] = (pOldX[oi]+pOldX[oi+1])/2; + pNewY[1+oi*3+1] = pOldY[oi+1]; + pNewZ[1+oi*3+1] = pOldZ[oi]; + // and now the normal one + pNewX[1+oi*3+2] = pOldX[oi+1]; + pNewY[1+oi*3+2] = pOldY[oi+1]; + pNewZ[1+oi*3+2] = pOldZ[oi+1]; + break; + case CurveStyle_STEP_CENTER_Y: + /** O + | + +-----+ + | + O + */ + // create the first intermediate point + pNewX[1+oi*3] = pOldX[oi]; + pNewY[1+oi*3] = (pOldY[oi]+pOldY[oi+1])/2; + pNewZ[1+oi*3] = pOldZ[oi]; + // create the second intermediate point + pNewX[1+oi*3+1] = pOldX[oi+1]; + pNewY[1+oi*3+1] = (pOldY[oi]+pOldY[oi+1])/2; + pNewZ[1+oi*3+1] = pOldZ[oi]; + // and now the normal one + pNewX[1+oi*3+2] = pOldX[oi+1]; + pNewY[1+oi*3+2] = pOldY[oi+1]; + pNewZ[1+oi*3+2] = pOldZ[oi+1]; + break; + default: + // this should never be executed + OSL_FAIL("Unknown curvestyle in AreaChart::create_stepped_line"); + } + } + } + Clipping::clipPolygonAtRectangle( aSteppedPoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly ); + + return true; +} + bool AreaChart::impl_createLine( VDataSeries* pSeries , drawing::PolyPolygonShape3D* pSeriesPoly , PlottingPositionHelper* pPosHelper ) @@ -309,8 +438,20 @@ bool AreaChart::impl_createLine( VDataSeries* pSeries lcl_removeDuplicatePoints( aSplinePoly, *pPosHelper ); Clipping::clipPolygonAtRectangle( aSplinePoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly ); } - else + else if (CurveStyle_STEP_START==m_eCurveStyle || + CurveStyle_STEP_END==m_eCurveStyle || + CurveStyle_STEP_CENTER_Y==m_eCurveStyle || + CurveStyle_STEP_CENTER_X==m_eCurveStyle + ) { + if (!create_stepped_line(*pSeriesPoly, m_eCurveStyle, pPosHelper, aPoly)) + { + return false; + } + } + else + { // default to creating a straight line + SAL_WARN_IF(CurveStyle_LINES != m_eCurveStyle, "chart2.areachart", "Unknown curve style"); bool bIsClipped = false; if( m_bConnectLastToFirstPoint && !ShapeFactory::isPolygonEmptyOrSinglePoint(*pSeriesPoly) ) { diff --git a/chart2/source/view/charttypes/AreaChart.hxx b/chart2/source/view/charttypes/AreaChart.hxx index cc8b9ae0012b..cb6ea9f3416d 100644 --- a/chart2/source/view/charttypes/AreaChart.hxx +++ b/chart2/source/view/charttypes/AreaChart.hxx @@ -80,6 +80,10 @@ private: //methods bool impl_createLine( VDataSeries* pSeries , ::com::sun::star::drawing::PolyPolygonShape3D* pSeriesPoly , PlottingPositionHelper* pPosHelper ); + bool create_stepped_line( ::com::sun::star::drawing::PolyPolygonShape3D aStartPoly + , ::com::sun::star::chart2::CurveStyle eCurveStyle + , PlottingPositionHelper* pPosHelper + , ::com::sun::star::drawing::PolyPolygonShape3D &aPoly ); private: //member PlottingPositionHelper* m_pMainPosHelper; -- cgit