Kaydet (Commit) bf033461 authored tarafından EricSeynaeve's avatar EricSeynaeve Kaydeden (comit) Markus Mohrhard

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
üst 91c8b357
......@@ -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);
}
......
......@@ -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) )
{
......
......@@ -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;
......
......@@ -48,7 +48,47 @@ enum CurveStyle
/**
*/
NURBS
NURBS,
/** Data points are connected via a 2-segmented stepped line.
The line starts horizontally.
O
|
|
|
O-----+
*/
STEP_START,
/** Data points are connected via a 2-segmented stepped line.
The line ends horizontally.
+------O
|
|
|
O
*/
STEP_END,
/** Data points are connected via a 3-segmented stepped line.
The lines is horizontal till the center of the X values.
+--O
|
|
|
O--+
*/
STEP_CENTER_X,
/** Data points are connected via a 3-segmented stepped line.
The lines is horizontal at the center of the Y values.
O
|
+-----+
|
O
*/
STEP_CENTER_Y
};
} ; // chart2
......
......@@ -2555,6 +2555,14 @@ namespace xmloff { namespace token {
XML_INTERPOLATION,
XML_CUBIC_SPLINE,
XML_B_SPLINE,
XML_STEP_START,
XML_STEP_END,
XML_STEP_CENTER_X,
XML_STEP_CENTER_Y,
XML_GNM_STEP_START,
XML_GNM_STEP_END,
XML_GNM_STEP_CENTER_X,
XML_GNM_STEP_CENTER_Y,
XML_N_DB_OASIS,
XML_SHOW_FILTER_BUTTON,
......
......@@ -290,10 +290,20 @@ SvXMLEnumMapEntry aXMLChartInterpolationTypeEnumMap[] =
{
// this is neither an enum nor a constants group, but just a
// documented long property
{ ::xmloff::token::XML_NONE, 0 },
{ ::xmloff::token::XML_CUBIC_SPLINE, 1 },
{ ::xmloff::token::XML_B_SPLINE, 2 },
{ ::xmloff::token::XML_TOKEN_INVALID,0 }
{ ::xmloff::token::XML_NONE, 0 },
{ ::xmloff::token::XML_CUBIC_SPLINE, 1 },
{ ::xmloff::token::XML_B_SPLINE, 2 },
{ ::xmloff::token::XML_STEP_START, 3 },
{ ::xmloff::token::XML_STEP_END, 4 },
{ ::xmloff::token::XML_STEP_CENTER_X, 5 },
{ ::xmloff::token::XML_STEP_CENTER_Y, 6 },
// the GNM values should only be used for reading Gnumeric ods files
// they should never be used for writing ods file
{ ::xmloff::token::XML_GNM_STEP_START, 7 },
{ ::xmloff::token::XML_GNM_STEP_END, 8 },
{ ::xmloff::token::XML_GNM_STEP_CENTER_X, 9 },
{ ::xmloff::token::XML_GNM_STEP_CENTER_Y, 10 },
{ ::xmloff::token::XML_TOKEN_INVALID, 0 }
};
SvXMLEnumMapEntry aXMLChartDataLabelPlacementEnumMap[] =
......
......@@ -2556,6 +2556,16 @@ namespace xmloff { namespace token {
TOKEN( "interpolation", XML_INTERPOLATION ),
TOKEN( "cubic-spline", XML_CUBIC_SPLINE ),
TOKEN( "b-spline", XML_B_SPLINE ),
TOKEN( "step-start", XML_STEP_START ),
TOKEN( "step-end", XML_STEP_END ),
TOKEN( "step-center-x", XML_STEP_CENTER_X ),
TOKEN( "step-center-y", XML_STEP_CENTER_Y ),
// the gnm: values should only used for reading Gnumeric ods file
// these values should never be written
TOKEN( "gnm:step-start", XML_GNM_STEP_START ),
TOKEN( "gnm:step-end", XML_GNM_STEP_END ),
TOKEN( "gnm:step-center-x", XML_GNM_STEP_CENTER_X ),
TOKEN( "gnm:step-center-y", XML_GNM_STEP_CENTER_Y ),
TOKEN( "urn:oasis:names:tc:opendocument:xmlns:database:1.0", XML_N_DB_OASIS ),
TOKEN( "show-filter-button", XML_SHOW_FILTER_BUTTON ),
......
......@@ -315,7 +315,7 @@ void XMLPropertiesTContext_Impl::StartElement(
break;
case XML_OPTACTION_INTERPOLATION:
{
// 0: none
// 0: none (default)
sal_Int32 nSplineType = 0;
if( IsXMLToken( rAttrValue, XML_CUBIC_SPLINE ))
nSplineType = 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment