Date: prev next · Thread: first prev next last
2013 Archives by date, by thread · List index


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/2476

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/76/2476/1

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 used in Gnumeric and keep this
during saves from LO.

Change-Id: I0f04a779de4b65326ed7ce6de56191f11b51c596
---
M chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
M chart2/source/view/charttypes/AreaChart.cxx
M chart2/source/view/charttypes/AreaChart.hxx
M offapi/com/sun/star/chart2/CurveStyle.idl
M xmloff/inc/xmloff/xmltoken.hxx
M xmloff/source/chart/PropertyMap.hxx
M xmloff/source/core/xmltoken.cxx
M xmloff/source/transform/StyleOASISTContext.cxx
8 files changed, 316 insertions(+), 22 deletions(-)



diff --git a/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx 
b/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
index d68bdc5..d3db08d 100644
--- a/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
+++ b/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
@@ -231,12 +231,41 @@
     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;
+        case chart2::CurveStyle_GNM_STEP_START:
+            nOuterValue = 7;
+            break;
+        case chart2::CurveStyle_GNM_STEP_END:
+            nOuterValue = 8;
+            break;
+        case chart2::CurveStyle_GNM_STEP_CENTER_X:
+            nOuterValue = 9;
+            break;
+        case chart2::CurveStyle_GNM_STEP_CENTER_Y:
+            nOuterValue = 10;
+            break;
+        default:
+            nOuterValue = 0;
+    }
 
     return uno::makeAny(nOuterValue);
 }
@@ -247,12 +276,42 @@
 
     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;
+        case 7:
+            aInnerValue = chart2::CurveStyle_GNM_STEP_START;
+            break;
+        case 8:
+            aInnerValue = chart2::CurveStyle_GNM_STEP_END;
+            break;
+        case 9:
+            aInnerValue = chart2::CurveStyle_GNM_STEP_CENTER_X;
+            break;
+        case 10:
+            aInnerValue = chart2::CurveStyle_GNM_STEP_CENTER_Y;
+            break;
+        default:
+            // TODO: add an error is nOuterValue != 0 and we're in debugging mode
+            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 a9e207c..a1bacc3 100644
--- a/chart2/source/view/charttypes/AreaChart.cxx
+++ b/chart2/source/view/charttypes/AreaChart.cxx
@@ -287,6 +287,140 @@
     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 ||
+             CurveStyle_GNM_STEP_START==eCurveStyle || CurveStyle_GNM_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:
+                case CurveStyle_GNM_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:
+                case CurveStyle_GNM_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:
+                case CurveStyle_GNM_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:
+                case CurveStyle_GNM_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 +443,23 @@
         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 ||
+             CurveStyle_GNM_STEP_START==m_eCurveStyle ||
+             CurveStyle_GNM_STEP_END==m_eCurveStyle ||
+             CurveStyle_GNM_STEP_CENTER_Y==m_eCurveStyle ||
+             CurveStyle_GNM_STEP_CENTER_X==m_eCurveStyle)
     {
+        if (!create_stepped_line(*pSeriesPoly, m_eCurveStyle, pPosHelper, aPoly))
+        {
+            return false;
+        }
+    }
+    else
+    { // default to creating a straight line
+        // TODO: in debugging mode, print a warning when the linetype is not CurveStyle_LINES
         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 cc8b9ae..cb6ea9f 100644
--- a/chart2/source/view/charttypes/AreaChart.hxx
+++ b/chart2/source/view/charttypes/AreaChart.hxx
@@ -80,6 +80,10 @@
     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;
diff --git a/offapi/com/sun/star/chart2/CurveStyle.idl b/offapi/com/sun/star/chart2/CurveStyle.idl
index 3164186..5a6fdac 100644
--- a/offapi/com/sun/star/chart2/CurveStyle.idl
+++ b/offapi/com/sun/star/chart2/CurveStyle.idl
@@ -46,6 +46,55 @@
      */
     B_SPLINES,
 
+    /** 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,
+
+    /** These have the same meaning as above,
+        but are linked to the older Gnumeric attributes before
+        ODF1.3 was approved.
+     */
+    GNM_STEP_START,
+    GNM_STEP_END,
+    GNM_STEP_CENTER_X,
+    GNM_STEP_CENTER_Y,
+
     /**
      */
     NURBS
diff --git a/xmloff/inc/xmloff/xmltoken.hxx b/xmloff/inc/xmloff/xmltoken.hxx
index e7e886e..96025e4 100644
--- a/xmloff/inc/xmloff/xmltoken.hxx
+++ b/xmloff/inc/xmloff/xmltoken.hxx
@@ -2555,6 +2555,14 @@
         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,
diff --git a/xmloff/source/chart/PropertyMap.hxx b/xmloff/source/chart/PropertyMap.hxx
index e8298a6..d455a4a 100644
--- a/xmloff/source/chart/PropertyMap.hxx
+++ b/xmloff/source/chart/PropertyMap.hxx
@@ -290,10 +290,18 @@
 {
     // 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 },
+    { ::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[] =
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index afd52ba..c2d94d4 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -2556,6 +2556,15 @@
         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 ),
+        // also understand the older Gnumeric tookens
+        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 ),
diff --git a/xmloff/source/transform/StyleOASISTContext.cxx 
b/xmloff/source/transform/StyleOASISTContext.cxx
index 6f7caf7..f5fc845 100644
--- a/xmloff/source/transform/StyleOASISTContext.cxx
+++ b/xmloff/source/transform/StyleOASISTContext.cxx
@@ -315,18 +315,26 @@
                     break;
                 case XML_OPTACTION_INTERPOLATION:
                     {
-                        // 0: none
-                        sal_Int32 nSplineType = 0;
+                        // 0: none (default)
+                        sal_Int32 nLineType = 0;
                         if( IsXMLToken( rAttrValue, XML_CUBIC_SPLINE ))
-                            nSplineType = 1;
+                            nLineType = 1;
                         else if( IsXMLToken( rAttrValue, XML_B_SPLINE ))
-                            nSplineType = 2;
+                            nLineType = 2;
+                        else if( IsXMLToken( rAttrValue, XML_STEP_START )    || IsXMLToken( 
rAttrValue, XML_GNM_STEP_START ) )
+                            nLineType = 3;
+                        else if( IsXMLToken( rAttrValue, XML_STEP_END )      || IsXMLToken( 
rAttrValue, XML_GNM_STEP_END ) )
+                            nLineType = 4;
+                        else if( IsXMLToken( rAttrValue, XML_STEP_CENTER_X ) || IsXMLToken( 
rAttrValue, XML_GNM_STEP_CENTER_X ) )
+                            nLineType = 5;
+                        else if( IsXMLToken( rAttrValue, XML_STEP_CENTER_Y ) || IsXMLToken( 
rAttrValue, XML_GNM_STEP_CENTER_Y ) )
+                            nLineType = 6;
 
                         pAttrList->AddAttribute(
                             GetTransformer().GetNamespaceMap().GetQNameByKey(
                                 XML_NAMESPACE_CHART,
                                 GetXMLToken( XML_SPLINES )),
-                            OUString::valueOf( nSplineType ));
+                            OUString::valueOf( nLineType ));
                     }
                     break;
                 case XML_OPTACTION_INTERVAL_MAJOR:

-- 
To view, visit https://gerrit.libreoffice.org/2476
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0f04a779de4b65326ed7ce6de56191f11b51c596
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: master
Gerrit-Owner: Eric Seynaeve <github@nosperse.com>


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.