summaryrefslogtreecommitdiffstats
path: root/chart2/source/view/axes
diff options
context:
space:
mode:
authorBjörn Milcke <bm@openoffice.org>2003-10-06 08:58:36 +0000
committerBjörn Milcke <bm@openoffice.org>2003-10-06 08:58:36 +0000
commit668c6b0245b6076ac8fb3f5d734795117188675e (patch)
tree363512534f7fae13719bddccb3a365e48ef7a8d3 /chart2/source/view/axes
parentINTEGRATION: CWS os20 (1.10.256); FILE MERGED (diff)
downloadcore-668c6b0245b6076ac8fb3f5d734795117188675e.tar.gz
core-668c6b0245b6076ac8fb3f5d734795117188675e.zip
initial import
Diffstat (limited to 'chart2/source/view/axes')
-rw-r--r--chart2/source/view/axes/ScaleAutomatism.cxx357
-rw-r--r--chart2/source/view/axes/TickmarkHelper.cxx797
-rw-r--r--chart2/source/view/axes/TickmarkHelper.hxx265
-rw-r--r--chart2/source/view/axes/VAxisProperties.cxx468
-rw-r--r--chart2/source/view/axes/VCoordinateSystem.cxx226
-rw-r--r--chart2/source/view/axes/makefile.mk91
6 files changed, 2204 insertions, 0 deletions
diff --git a/chart2/source/view/axes/ScaleAutomatism.cxx b/chart2/source/view/axes/ScaleAutomatism.cxx
new file mode 100644
index 000000000000..6f9c14700778
--- /dev/null
+++ b/chart2/source/view/axes/ScaleAutomatism.cxx
@@ -0,0 +1,357 @@
+/*************************************************************************
+ *
+ * $RCSfile: ScaleAutomatism.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2003 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include "ScaleAutomatism.hxx"
+#include "macros.hxx"
+#include "TickmarkHelper.hxx"
+
+#ifndef _COM_SUN_STAR_LANG_XSERVICENAME_HPP_
+#include <com/sun/star/lang/XServiceName.hpp>
+#endif
+
+#ifndef INCLUDED_RTL_MATH_HXX
+#include <rtl/math.hxx>
+#endif
+
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::drafts::com::sun::star::chart2;
+
+ScaleAutomatism::ScaleAutomatism( const ScaleData& rSourceScale )
+ : m_fValueMinimum( 0.0 )
+ , m_fValueMaximum( 0.0 )
+ , m_nMaximumAutomaticMainIncrementCount(10)
+ , m_aSourceScale( rSourceScale )
+ , m_aSourceIncrement()
+ , m_aSourceSubIncrementList()
+{
+ ::rtl::math::setNan( &m_fValueMinimum );
+ ::rtl::math::setNan( &m_fValueMaximum );
+}
+
+ScaleAutomatism::ScaleAutomatism( const ScaleData& rSourceScale
+ , const IncrementData& rSourceIncrement
+ , const uno::Sequence< SubIncrement >& rSourceSubIncrementList )
+ : m_fValueMinimum( 0.0 )
+ , m_fValueMaximum( 0.0 )
+ , m_nMaximumAutomaticMainIncrementCount(9)
+ , m_aSourceScale( rSourceScale )
+ , m_aSourceIncrement( rSourceIncrement )
+ , m_aSourceSubIncrementList( rSourceSubIncrementList )
+{
+ ::rtl::math::setNan( &m_fValueMinimum );
+ ::rtl::math::setNan( &m_fValueMaximum );
+}
+
+ScaleAutomatism::~ScaleAutomatism()
+{
+}
+
+//@todo these method should become part of the scaling interface and implementation somehow
+//@todo problem with outparamters at api
+ExplicitIncrementData getExplicitIncrementAndScaleForLogarithm(
+ bool bChangeMinimumToIncrementRythm, bool bChangeMaximumToIncrementRythm
+ , sal_Int32 nMaximumAutomaticMainIncrementCount
+ , ExplicitScaleData& rExplicitScale
+ , const IncrementData& rSourceIncrement
+ , const uno::Sequence< SubIncrement >& rSourceSubIncrementList )
+{
+ //minimum and maximum of the ExplicitScaleData may be changed
+ //to suiteable values if allowed
+ //but they will definitly be changed if they are out of allowed borders
+
+ if( nMaximumAutomaticMainIncrementCount <= 0 )
+ nMaximumAutomaticMainIncrementCount = 5;
+
+ //make sure that minimum and maximum are not out of allowed range
+ {
+ if( rExplicitScale.Maximum<=0.0 )
+ rExplicitScale.Maximum = 100.0;
+ if( rExplicitScale.Minimum<=0.0 )
+ {
+ rExplicitScale.Minimum = 0.1;
+ if( rExplicitScale.Minimum >= rExplicitScale.Maximum )
+ rExplicitScale.Minimum = log(rExplicitScale.Maximum)/10.0;
+ }
+ }
+
+ ExplicitIncrementData aRet;
+ if(!(rSourceIncrement.PostEquidistant>>=aRet.PostEquidistant))
+ {
+ //maybe scaling dependent
+ aRet.PostEquidistant = sal_True;
+ }
+ if(!(rSourceIncrement.Distance>>=aRet.Distance))
+ {
+ //autocalculate the distance
+ if(aRet.PostEquidistant && rExplicitScale.Scaling.is() )
+ {
+ double fRange = rExplicitScale.Scaling->doScaling( rExplicitScale.Maximum )
+ - rExplicitScale.Scaling->doScaling( rExplicitScale.Minimum );
+ double fSlice = fRange/nMaximumAutomaticMainIncrementCount;
+ //make a fine value out of fSlice now:
+ //only integers are reasonable as distance values
+ sal_Int32 nDistance = static_cast<sal_Int32>(fSlice);
+ if(nDistance<=0)
+ nDistance=1;
+ aRet.Distance = nDistance;
+ }
+ else
+ {
+ //@todo this was not tested
+ double fRange = rExplicitScale.Maximum - rExplicitScale.Minimum;
+ double fSlice = fRange/nMaximumAutomaticMainIncrementCount;
+ //make a fine value out of fSlice now:
+ double fSliceMagnitude = pow (10, floor (log10 (fSlice)));
+ aRet.Distance = static_cast<sal_Int32>(fSlice/fSliceMagnitude)*fSliceMagnitude;
+ }
+ }
+
+ if(!(rSourceIncrement.BaseValue>>=aRet.BaseValue))
+ {
+ //scaling dependent
+ //@maybe todo is this default also plotter dependent ??
+ aRet.BaseValue = 1.0;
+ }
+ else if( aRet.BaseValue<=0.0 ) //make sure that BaseValue is not out of allowed ranges
+ aRet.BaseValue = 1.0;
+
+ if(bChangeMinimumToIncrementRythm)
+ {
+ double fMin = rExplicitScale.Minimum;
+ if( aRet.PostEquidistant && rExplicitScale.Scaling.is() )
+ fMin = rExplicitScale.Scaling->doScaling(fMin);
+
+ fMin = TickmarkHelper::getMinimumAtIncrement( fMin, aRet );
+ if( aRet.PostEquidistant && rExplicitScale.Scaling.is() )
+ fMin = rExplicitScale.Scaling->getInverseScaling()->doScaling(fMin);
+ rExplicitScale.Minimum = fMin;
+
+ if( rExplicitScale.Minimum<=0.0 )
+ {
+ rExplicitScale.Minimum = 0.1;
+ if( rExplicitScale.Minimum >= rExplicitScale.Maximum )
+ rExplicitScale.Minimum = log(rExplicitScale.Maximum)/10.0;
+ }
+ }
+ if(bChangeMaximumToIncrementRythm)
+ {
+ double fMax = rExplicitScale.Maximum;
+ if( aRet.PostEquidistant && rExplicitScale.Scaling.is() )
+ fMax = rExplicitScale.Scaling->doScaling(fMax);
+ fMax = TickmarkHelper::getMaximumAtIncrement( fMax, aRet );
+ if( aRet.PostEquidistant && rExplicitScale.Scaling.is() )
+ fMax = rExplicitScale.Scaling->getInverseScaling()->doScaling(fMax);
+ rExplicitScale.Maximum = fMax;
+ }
+ //---------------------------------------------------------------
+ //fill explicit sub increment
+ sal_Int32 nSubCount = rSourceSubIncrementList.getLength();
+ aRet.SubIncrements.realloc(nSubCount);
+ for( sal_Int32 nN=0; nN<nSubCount; nN++ )
+ {
+ const SubIncrement& rSubIncrement = rSourceSubIncrementList[nN];
+ ExplicitSubIncrement& rExplicitSubIncrement = aRet.SubIncrements[nN];
+
+ if(!(rSubIncrement.IntervalCount>>=rExplicitSubIncrement.IntervalCount))
+ {
+ //scaling dependent
+ //@todo autocalculate IntervalCount dependent on MainIncrement and scaling
+ rExplicitSubIncrement.IntervalCount = 5;
+ }
+ if(!(rSubIncrement.PostEquidistant>>=rExplicitSubIncrement.PostEquidistant))
+ {
+ //scaling dependent
+ rExplicitSubIncrement.PostEquidistant = sal_False;
+ }
+ }
+ return aRet;
+}
+
+ExplicitIncrementData getExplicitIncrementAndScaleForLinear(
+ bool bChangeMinimumToIncrementRythm, bool bChangeMaximumToIncrementRythm
+ , sal_Int32 nMaximumAutomaticMainIncrementCount
+ , ExplicitScaleData& rExplicitScale
+ , const IncrementData& rSourceIncrement
+ , const uno::Sequence< SubIncrement >& rSourceSubIncrementList )
+{
+ //minimum and maximum of the ExplicitScaleData may be changed
+ //to suiteable values if allowed
+ //but they will definitly be changed if they are out of allowed borders
+
+ ExplicitIncrementData aRet;
+ if(!(rSourceIncrement.PostEquidistant>>=aRet.PostEquidistant))
+ {
+ //maybe scaling dependent
+ aRet.PostEquidistant = sal_True;
+ }
+ if(!(rSourceIncrement.Distance>>=aRet.Distance))
+ {
+ //autocalculate the distance
+ double fRange = rExplicitScale.Maximum - rExplicitScale.Minimum;
+ double fSlice = fRange/nMaximumAutomaticMainIncrementCount;
+
+ //make a fine value out of fSlice now:
+ double fSliceMagnitude = pow (10, floor (log10 (fSlice)));
+ fSlice /= fSliceMagnitude;
+ if(fSlice<=1.0)
+ fSlice=1.0;
+ else if( fSlice<= 2.0 )
+ fSlice=2.0;
+ else if( fSlice<= 2.5 )
+ fSlice=2.5;
+ else if( fSlice<= 5.0)
+ fSlice=5.0;
+ else
+ fSlice=10.0;
+
+ aRet.Distance = fSlice*fSliceMagnitude;
+ }
+ if(!(rSourceIncrement.BaseValue>>=aRet.BaseValue))
+ {
+ //@maybe todo is this default also plotter dependent ??
+ aRet.BaseValue = 0.0;
+ }
+ if(bChangeMinimumToIncrementRythm)
+ {
+ rExplicitScale.Minimum = TickmarkHelper::getMinimumAtIncrement( rExplicitScale.Minimum, aRet );
+ }
+ if(bChangeMaximumToIncrementRythm)
+ {
+ rExplicitScale.Maximum = TickmarkHelper::getMaximumAtIncrement( rExplicitScale.Maximum, aRet );
+ }
+ //---------------------------------------------------------------
+ //fill explicit sub increment
+ sal_Int32 nSubCount = rSourceSubIncrementList.getLength();
+ aRet.SubIncrements.realloc(nSubCount);
+ for( sal_Int32 nN=0; nN<nSubCount; nN++ )
+ {
+ const SubIncrement& rSubIncrement = rSourceSubIncrementList[nN];
+ ExplicitSubIncrement& rExplicitSubIncrement = aRet.SubIncrements[nN];
+
+ if(!(rSubIncrement.IntervalCount>>=rExplicitSubIncrement.IntervalCount))
+ {
+ //scaling dependent
+ //@todo autocalculate IntervalCount dependent on MainIncrement and scaling
+ rExplicitSubIncrement.IntervalCount = 2;
+ }
+ if(!(rSubIncrement.PostEquidistant>>=rExplicitSubIncrement.PostEquidistant))
+ {
+ //scaling dependent
+ rExplicitSubIncrement.PostEquidistant = sal_False;
+ }
+ }
+ return aRet;
+}
+
+void ScaleAutomatism::calculateExplicitScaleAndIncrement(
+ ExplicitScaleData& rExplicitScale
+ , ExplicitIncrementData& rExplicitIncrement )
+{
+ //---------------------------------------------------------------
+ //fill explicit scale
+ bool bChangeMinimumToIncrementRythm=false, bChangeMaximumToIncrementRythm=false;
+ if(!(m_aSourceScale.Minimum>>=rExplicitScale.Minimum))
+ {
+ //autocalculate the minimum in first iteration
+ //the increment is considered below
+ if( !::rtl::math::isNan(m_fValueMinimum) )
+ rExplicitScale.Minimum = m_fValueMinimum;
+ else
+ rExplicitScale.Minimum = 0.0;//@todo get Minimum from scsaling or from plotter????
+ bChangeMinimumToIncrementRythm = true;
+ }
+ if(!(m_aSourceScale.Maximum>>=rExplicitScale.Maximum))
+ {
+ //autocalculate the maximum in first iteration
+ //the increment is considered below
+ if( !::rtl::math::isNan(m_fValueMaximum) )
+ rExplicitScale.Maximum = m_fValueMaximum;
+ else
+ rExplicitScale.Maximum = 10.0;//@todo get Maximum from scaling or from plotter????
+ bChangeMaximumToIncrementRythm=true;
+ }
+ rExplicitScale.Orientation = m_aSourceScale.Orientation;//AxisOrientation_MATHEMATICAL;
+ rExplicitScale.Scaling = m_aSourceScale.Scaling;
+ rExplicitScale.Breaks = m_aSourceScale.Breaks;
+ //---------------------------------------------------------------
+ //fill explicit increment
+ //minimum and maximum of the ExplicitScaleData may be changed if allowed
+ uno::Reference< lang::XServiceName > xServiceName( rExplicitScale.Scaling, uno::UNO_QUERY );
+ bool bIsLogarithm = ( xServiceName.is() && (xServiceName->getServiceName()).equals(
+ C2U( "com.sun.star.chart2.LogarithmicScaling" )));
+ if(bIsLogarithm)
+ rExplicitIncrement = getExplicitIncrementAndScaleForLogarithm( bChangeMinimumToIncrementRythm, bChangeMaximumToIncrementRythm, m_nMaximumAutomaticMainIncrementCount
+ , rExplicitScale, m_aSourceIncrement, m_aSourceSubIncrementList );
+ else
+ rExplicitIncrement = getExplicitIncrementAndScaleForLinear( bChangeMinimumToIncrementRythm, bChangeMaximumToIncrementRythm, m_nMaximumAutomaticMainIncrementCount
+ , rExplicitScale, m_aSourceIncrement, m_aSourceSubIncrementList );
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/view/axes/TickmarkHelper.cxx b/chart2/source/view/axes/TickmarkHelper.cxx
new file mode 100644
index 000000000000..5c2563f134a7
--- /dev/null
+++ b/chart2/source/view/axes/TickmarkHelper.cxx
@@ -0,0 +1,797 @@
+/*************************************************************************
+ *
+ * $RCSfile: TickmarkHelper.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2003 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include "TickmarkHelper.hxx"
+#include "ViewDefines.hxx"
+
+#ifndef INCLUDED_RTL_MATH_HXX
+#include <rtl/math.hxx>
+#endif
+#ifndef _TOOLS_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::drafts::com::sun::star::chart2;
+using namespace ::rtl::math;
+
+TickInfo::TickInfo()
+: fScaledTickValue( 0.0 )
+, fUnscaledTickValue( 0.0 )
+, nScreenTickValue( 0 )
+, bPaintIt( true )
+, xTextShape( NULL )
+{
+}
+
+void TickInfo::updateUnscaledValue( const uno::Reference< XScaling >& xInverseScaling )
+{
+ if( xInverseScaling.is() )
+ this->fUnscaledTickValue = xInverseScaling->doScaling( this->fScaledTickValue );
+ else
+ this->fUnscaledTickValue = this->fScaledTickValue;
+}
+
+TickIter::TickIter( const uno::Sequence< uno::Sequence< double > >& rTicks
+ , const ExplicitIncrementData& rIncrement
+ , sal_Int32 nMinDepth, sal_Int32 nMaxDepth )
+ : m_pSimpleTicks(&rTicks), m_pInfoTicks(NULL)
+ , m_rIncrement(rIncrement)
+ , m_nMinDepth(0), m_nMaxDepth(0)
+ , m_nTickCount(0), m_pnPositions(NULL)
+ , m_pnPreParentCount(NULL), m_pbIntervalFinished(NULL)
+ , m_nCurrentDepth(-1), m_nCurrentPos(-1), m_fCurrentValue( 0.0 )
+{
+ initIter( nMinDepth, nMaxDepth );
+}
+
+TickIter::TickIter( ::std::vector< ::std::vector< TickInfo > >& rTicks
+ , const ExplicitIncrementData& rIncrement
+ , sal_Int32 nMinDepth, sal_Int32 nMaxDepth )
+ : m_pSimpleTicks(NULL), m_pInfoTicks(&rTicks)
+ , m_rIncrement(rIncrement)
+ , m_nMinDepth(0), m_nMaxDepth(0)
+ , m_nTickCount(0), m_pnPositions(NULL)
+ , m_pnPreParentCount(NULL), m_pbIntervalFinished(NULL)
+ , m_nCurrentDepth(-1), m_nCurrentPos(-1), m_fCurrentValue( 0.0 )
+{
+ initIter( nMinDepth, nMaxDepth );
+}
+
+void TickIter::initIter( sal_Int32 nMinDepth, sal_Int32 nMaxDepth )
+{
+ m_nMaxDepth = nMaxDepth;
+ if(nMaxDepth<0 || m_nMaxDepth>_getMaxDepth())
+ m_nMaxDepth=_getMaxDepth();
+
+ sal_Int32 nDepth = 0;
+ for( nDepth = 0; nDepth<=m_nMaxDepth ;nDepth++ )
+ m_nTickCount += _getTickCount(nDepth);
+
+ if(!m_nTickCount)
+ return;
+
+ m_pnPositions = new sal_Int32[m_nMaxDepth+1];
+
+ m_pnPreParentCount = new sal_Int32[m_nMaxDepth+1];
+ m_pbIntervalFinished = new bool[m_nMaxDepth+1];
+ m_pnPreParentCount[0] = 0;
+ m_pbIntervalFinished[0] = false;
+ double fParentValue = _getTickValue(0,0);
+ for( nDepth = 1; nDepth<=m_nMaxDepth ;nDepth++ )
+ {
+ m_pbIntervalFinished[nDepth] = false;
+
+ sal_Int32 nPreParentCount = 0;
+ sal_Int32 nCount = _getTickCount(nDepth);
+ for(sal_Int32 nN = 0; nN<nCount; nN++)
+ {
+ if(_getTickValue(nDepth,nN) < fParentValue)
+ nPreParentCount++;
+ else
+ break;
+ }
+ m_pnPreParentCount[nDepth] = nPreParentCount;
+ if(nCount)
+ {
+ double fNextParentValue = _getTickValue(nDepth,0);
+ if( fNextParentValue < fParentValue )
+ fParentValue = fNextParentValue;
+ }
+ }
+}
+
+TickIter::~TickIter()
+{
+ delete[] m_pnPositions;
+ delete[] m_pnPreParentCount;
+ delete[] m_pbIntervalFinished;
+}
+
+sal_Int32 TickIter::getStartDepth() const
+{
+ //find the depth of the first visible tickmark:
+ //it is the depth of the smallest value
+ sal_Int32 nReturnDepth=0;
+ double fMinValue = DBL_MAX;
+ for(sal_Int32 nDepth = 0; nDepth<=m_nMaxDepth ;nDepth++ )
+ {
+ sal_Int32 nCount = _getTickCount(nDepth);
+ if( !nCount )
+ continue;
+ double fThisValue = _getTickValue(nDepth,0);
+ if(fThisValue<fMinValue)
+ {
+ nReturnDepth = nDepth;
+ fMinValue = fThisValue;
+ }
+ }
+ return nReturnDepth;
+}
+
+double* TickIter::firstValue()
+{
+ if( gotoFirst() )
+ {
+ m_fCurrentValue = _getTickValue(m_nCurrentDepth, m_pnPositions[m_nCurrentDepth]);
+ return &m_fCurrentValue;
+ }
+ return NULL;
+}
+
+TickInfo* TickIter::firstInfo()
+{
+ if( m_pInfoTicks && gotoFirst() )
+ return &(*m_pInfoTicks)[m_nCurrentDepth][m_pnPositions[m_nCurrentDepth]];
+ return NULL;
+}
+
+sal_Int32 TickIter::getIntervalCount( sal_Int32 nDepth )
+{
+ if(nDepth>m_rIncrement.SubIncrements.getLength() || nDepth<0)
+ return 0;
+
+ if(!nDepth)
+ return m_nTickCount;
+
+ return m_rIncrement.SubIncrements[nDepth-1].IntervalCount;
+}
+
+bool TickIter::isAtLastPartTick()
+{
+ if(!m_nCurrentDepth)
+ return false;
+ sal_Int32 nIntervalCount = getIntervalCount( m_nCurrentDepth );
+ if(!nIntervalCount || nIntervalCount == 1)
+ return true;
+ if( m_pbIntervalFinished[m_nCurrentDepth] )
+ return false;
+ sal_Int32 nPos = m_pnPositions[m_nCurrentDepth]+1;
+ if(m_pnPreParentCount[m_nCurrentDepth])
+ nPos += nIntervalCount-1 - m_pnPreParentCount[m_nCurrentDepth];
+ bool bRet = nPos && nPos % (nIntervalCount-1) == 0;
+ if(!nPos && !m_pnPreParentCount[m_nCurrentDepth]
+ && m_pnPositions[m_nCurrentDepth-1]==-1 )
+ bRet = true;
+ return bRet;
+}
+
+bool TickIter::gotoFirst()
+{
+ if( m_nMaxDepth<0 )
+ return false;
+ if( !m_nTickCount )
+ return false;
+
+ for(sal_Int32 nDepth = 0; nDepth<=m_nMaxDepth ;nDepth++ )
+ m_pnPositions[nDepth] = -1;
+
+ m_nCurrentPos = 0;
+ m_nCurrentDepth = getStartDepth();
+ m_pnPositions[m_nCurrentDepth] = 0;
+ return true;
+}
+
+bool TickIter::gotoNext()
+{
+ if( m_nCurrentPos < 0 )
+ return false;
+ m_nCurrentPos++;
+
+ if( m_nCurrentPos >= m_nTickCount )
+ return false;
+
+ if( m_nCurrentDepth==m_nMaxDepth && isAtLastPartTick() )
+ {
+ do
+ {
+ m_pbIntervalFinished[m_nCurrentDepth] = true;
+ m_nCurrentDepth--;
+ }
+ while( m_nCurrentDepth && isAtLastPartTick() );
+ }
+ else if( m_nCurrentDepth<m_nMaxDepth )
+ {
+ do
+ {
+ m_nCurrentDepth++;
+ }
+ while( m_nCurrentDepth<m_nMaxDepth );
+ }
+ m_pbIntervalFinished[m_nCurrentDepth] = false;
+ m_pnPositions[m_nCurrentDepth] = m_pnPositions[m_nCurrentDepth]+1;
+ return true;
+}
+
+double* TickIter::nextValue()
+{
+ if( gotoNext() )
+ {
+ m_fCurrentValue = _getTickValue(m_nCurrentDepth, m_pnPositions[m_nCurrentDepth]);
+ return &m_fCurrentValue;
+ }
+ return NULL;
+}
+
+TickInfo* TickIter::nextInfo()
+{
+ if( m_pInfoTicks && gotoNext() )
+ return &(*m_pInfoTicks)[m_nCurrentDepth][m_pnPositions[m_nCurrentDepth]];
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//static
+double TickmarkHelper::getMinimumAtIncrement( double fMin, const ExplicitIncrementData& rIncrement )
+{
+ //the returned value will be <= fMin and on a Major Tick given by rIncrement
+ if(rIncrement.Distance<=0.0)
+ return fMin;
+
+ double fRet = rIncrement.BaseValue +
+ static_cast<sal_Int32>(
+ approxSub( fMin, rIncrement.BaseValue )
+ / rIncrement.Distance)
+ *rIncrement.Distance;
+
+ if( fRet > fMin )
+ {
+ if( !approxEqual(fRet, fMin) )
+ fRet -= rIncrement.Distance;
+ }
+ return fRet;
+}
+//static
+double TickmarkHelper::getMaximumAtIncrement( double fMax, const ExplicitIncrementData& rIncrement )
+{
+ //the returned value will be >= fMax and on a Major Tick given by rIncrement
+ if(rIncrement.Distance<=0.0)
+ return fMax;
+
+ double fRet = rIncrement.BaseValue +
+ static_cast<sal_Int32>(
+ approxSub( fMax, rIncrement.BaseValue )
+ / rIncrement.Distance)
+ *rIncrement.Distance;
+
+ if( fRet < fMax )
+ {
+ if( !approxEqual(fRet, fMax) )
+ fRet += rIncrement.Distance;
+ }
+ return fRet;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+TickmarkHelper::TickmarkHelper(
+ const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement )
+ : m_rScale( rScale )
+ , m_rIncrement( rIncrement )
+ , m_xInverseScaling(NULL)
+ , m_pfCurrentValues(NULL)
+{
+ //@todo: make sure that the scale is valid for the scaling
+
+ m_pfCurrentValues = new double[getTickDepth()];
+
+ if( m_rScale.Scaling.is() )
+ {
+ m_xInverseScaling = m_rScale.Scaling->getInverseScaling();
+ DBG_ASSERT( m_xInverseScaling.is(), "each Scaling needs to return a inverse Scaling" );
+ }
+
+ double fMin = m_fScaledVisibleMin = m_rScale.Minimum;
+ if( m_xInverseScaling.is() )
+ {
+ m_fScaledVisibleMin = m_rScale.Scaling->doScaling(m_fScaledVisibleMin);
+ if(m_rIncrement.PostEquidistant )
+ fMin = m_fScaledVisibleMin;
+ }
+
+ double fMax = m_fScaledVisibleMax = m_rScale.Maximum;
+ if( m_xInverseScaling.is() )
+ {
+ m_fScaledVisibleMax = m_rScale.Scaling->doScaling(m_fScaledVisibleMax);
+ if(m_rIncrement.PostEquidistant )
+ fMax = m_fScaledVisibleMax;
+ }
+
+ //--
+ m_fOuterMajorTickBorderMin = TickmarkHelper::getMinimumAtIncrement( fMin, m_rIncrement );
+ m_fOuterMajorTickBorderMax = TickmarkHelper::getMaximumAtIncrement( fMax, m_rIncrement );
+ //--
+
+ m_fOuterMajorTickBorderMin_Scaled = m_fOuterMajorTickBorderMin;
+ m_fOuterMajorTickBorderMax_Scaled = m_fOuterMajorTickBorderMax;
+ if(!m_rIncrement.PostEquidistant && m_xInverseScaling.is() )
+ {
+ m_fOuterMajorTickBorderMin_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMin);
+ m_fOuterMajorTickBorderMax_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMax);
+
+ //check validity of new range: m_fOuterMajorTickBorderMin <-> m_fOuterMajorTickBorderMax
+ //it is assumed here, that the original range in the given Scale is valid
+ if( !rtl::math::isFinite(m_fOuterMajorTickBorderMin_Scaled) )
+ {
+ m_fOuterMajorTickBorderMin += m_rIncrement.Distance;
+ m_fOuterMajorTickBorderMin_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMin);
+ }
+ if( !rtl::math::isFinite(m_fOuterMajorTickBorderMax_Scaled) )
+ {
+ m_fOuterMajorTickBorderMax -= m_rIncrement.Distance;
+ m_fOuterMajorTickBorderMax_Scaled = m_rScale.Scaling->doScaling(m_fOuterMajorTickBorderMax);
+ }
+ }
+}
+
+TickmarkHelper::~TickmarkHelper()
+{
+ delete[] m_pfCurrentValues;
+}
+
+sal_Int32 TickmarkHelper::getTickDepth() const
+{
+ return m_rIncrement.SubIncrements.getLength() + 1;
+}
+
+sal_Int32 TickmarkHelper::getMaxTickCount( sal_Int32 nDepth ) const
+{
+ //return the maximum amount of ticks
+ //possibly open intervals at the two ends of the region are handled as if they were completely visible
+ //(this is necessary for calculating the sub ticks at the borders correctly)
+
+ if( nDepth >= getTickDepth() )
+ return 0;
+ if( m_fOuterMajorTickBorderMax < m_fOuterMajorTickBorderMin )
+ return 0;
+
+ sal_Int32 nIntervalCount;
+ if(m_rIncrement.PostEquidistant )
+ nIntervalCount = static_cast<sal_Int32>
+ ( approxSub( m_fScaledVisibleMax, m_fScaledVisibleMin )
+ / m_rIncrement.Distance );
+ else
+ nIntervalCount = static_cast<sal_Int32>
+ ( approxSub( m_rScale.Maximum, m_rScale.Minimum )
+ / m_rIncrement.Distance );
+ nIntervalCount+=3;
+ for(sal_Int32 nN=0; nN<nDepth-1; nN++)
+ {
+ if( m_rIncrement.SubIncrements[nN].IntervalCount>1 )
+ nIntervalCount *= m_rIncrement.SubIncrements[nN].IntervalCount;
+ }
+
+ sal_Int32 nTickCount = nIntervalCount;
+ if(nDepth>0 && m_rIncrement.SubIncrements[nDepth-1].IntervalCount>1)
+ nTickCount = nIntervalCount * (m_rIncrement.SubIncrements[nDepth-1].IntervalCount-1);
+
+ return nTickCount;
+}
+
+double* TickmarkHelper::getMajorTick( sal_Int32 nTick ) const
+{
+ m_pfCurrentValues[0] = m_fOuterMajorTickBorderMin + nTick*m_rIncrement.Distance;
+
+ if(m_pfCurrentValues[0]>m_fOuterMajorTickBorderMax)
+ return NULL;
+ if(m_pfCurrentValues[0]<m_fOuterMajorTickBorderMin)
+ return NULL;
+
+ //return always the value after scaling
+ if(!m_rIncrement.PostEquidistant && m_xInverseScaling.is() )
+ m_pfCurrentValues[0] = m_rScale.Scaling->doScaling( m_pfCurrentValues[0] );
+
+ return &m_pfCurrentValues[0];
+}
+
+double* TickmarkHelper::getMinorTick( sal_Int32 nTick, sal_Int32 nDepth
+ , double fStartParentTick, double fNextParentTick ) const
+{
+ //check validity of arguments
+ {
+ //DBG_ASSERT( fStartParentTick < fNextParentTick, "fStartParentTick >= fNextParentTick");
+ if(fStartParentTick >= fNextParentTick)
+ return NULL;
+ if(nDepth>m_rIncrement.SubIncrements.getLength() || nDepth<=0)
+ return NULL;
+
+ //subticks are only calculated if they are laying between parent ticks:
+ if(nTick<=0)
+ return NULL;
+ if(nTick>=m_rIncrement.SubIncrements[nDepth-1].IntervalCount)
+ return NULL;
+ }
+
+ bool bPostEquidistant = m_rIncrement.SubIncrements[nDepth-1].PostEquidistant;
+
+ double fAdaptedStartParent = fStartParentTick;
+ double fAdaptedNextParent = fNextParentTick;
+
+ if( !bPostEquidistant && m_xInverseScaling.is() )
+ {
+ fAdaptedStartParent = m_xInverseScaling->doScaling(fStartParentTick);
+ fAdaptedNextParent = m_xInverseScaling->doScaling(fNextParentTick);
+ }
+
+ double fDistance = (fAdaptedNextParent - fAdaptedStartParent)/m_rIncrement.SubIncrements[nDepth-1].IntervalCount;
+
+ m_pfCurrentValues[nDepth] = fAdaptedStartParent + nTick*fDistance;
+ double& fTest = m_pfCurrentValues[nDepth];
+
+ //return always the value after scaling
+ if(!bPostEquidistant && m_xInverseScaling.is() )
+ m_pfCurrentValues[nDepth] = m_rScale.Scaling->doScaling( m_pfCurrentValues[nDepth] );
+
+ if( !isWithinOuterBorder( m_pfCurrentValues[nDepth] ) )
+ return NULL;
+
+ return &m_pfCurrentValues[nDepth];
+}
+
+bool TickmarkHelper::isWithinOuterBorder( double fScaledValue ) const
+{
+ if(fScaledValue>m_fOuterMajorTickBorderMax_Scaled)
+ return false;
+ if(fScaledValue<m_fOuterMajorTickBorderMin_Scaled)
+ return false;
+
+ return true;
+}
+
+
+bool TickmarkHelper::isVisible( double fScaledValue ) const
+{
+ if(fScaledValue>m_fScaledVisibleMax)
+ return false;
+ if(fScaledValue<m_fScaledVisibleMin)
+ return false;
+
+ return true;
+}
+
+bool TickmarkHelper::isPostEquidistant( sal_Int32 nDepth ) const
+{
+ if( nDepth<0 || nDepth>m_rIncrement.SubIncrements.getLength() )
+ {
+ DBG_ERROR("invalid depth for tickmark");
+ return true;
+ }
+
+ if( nDepth==0 )
+ return m_rIncrement.PostEquidistant;
+
+ return m_rIncrement.SubIncrements[nDepth-1].PostEquidistant;
+}
+
+void TickmarkHelper::getAllTicks( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
+{
+ uno::Sequence< uno::Sequence< double > > aAllTicks;
+
+ //create point sequences for each tick depth
+ sal_Int32 nDepthCount = this->getTickDepth();
+ sal_Int32 nMaxMajorTickCount = this->getMaxTickCount( 0 );
+
+ aAllTicks.realloc(nDepthCount);
+ aAllTicks[0].realloc(nMaxMajorTickCount);
+
+ sal_Int32 nRealMajorTickCount = 0;
+ double* pValue = NULL;
+ for( sal_Int32 nMajorTick=0; nMajorTick<nMaxMajorTickCount; nMajorTick++ )
+ {
+ pValue = this->getMajorTick( nMajorTick );
+ if(!pValue)
+ continue;
+ aAllTicks[0][nRealMajorTickCount] = *pValue;
+ nRealMajorTickCount++;
+ }
+ if(!nRealMajorTickCount)
+ return;
+ aAllTicks[0].realloc(nRealMajorTickCount);
+
+ if(nDepthCount>0)
+ this->addSubTicks( 1, aAllTicks );
+
+ //so far we have added all ticks between the outer major tick marks
+ //this was necessary to create sub ticks correctly
+ //now we reduce all ticks to the visible ones that lie between the real borders
+ sal_Int32 nDepth = 0;
+ for( nDepth = 0; nDepth < nDepthCount; nDepth++)
+ {
+ sal_Int32 nInvisibleAtLowerBorder = 0;
+ sal_Int32 nInvisibleAtUpperBorder = 0;
+ //we need only to check all ticks within the first major interval at each border
+ sal_Int32 nCheckCount = 1;
+ for(sal_Int32 nN=0; nN<nDepth; nN++)
+ {
+ if( m_rIncrement.SubIncrements[nN].IntervalCount>1 )
+ nCheckCount *= m_rIncrement.SubIncrements[nN].IntervalCount;
+ }
+ uno::Sequence< double >& rTicks = aAllTicks[nDepth];
+ sal_Int32 nCount = rTicks.getLength();
+ //check lower border
+ for( sal_Int32 nTick=0; nTick<nCheckCount && nTick<nCount; nTick++)
+ {
+ if( !isVisible( rTicks[nTick] ) )
+ nInvisibleAtLowerBorder++;
+ }
+ //check upper border
+ for( nTick=nCount-1; nTick>nCount-1-nCheckCount && nTick>=0; nTick--)
+ {
+ if( !isVisible( rTicks[nTick] ) )
+ nInvisibleAtUpperBorder++;
+ }
+ //resize sequence
+ if( !nInvisibleAtLowerBorder && !nInvisibleAtUpperBorder)
+ continue;
+ if( !nInvisibleAtLowerBorder )
+ rTicks.realloc(nCount-nInvisibleAtUpperBorder);
+ else
+ {
+ sal_Int32 nNewCount = nCount-nInvisibleAtUpperBorder-nInvisibleAtLowerBorder;
+ if(nNewCount<0)
+ nNewCount=0;
+
+ uno::Sequence< double > aOldTicks(rTicks);
+ rTicks.realloc(nNewCount);
+ for(sal_Int32 nTick = 0; nTick<nNewCount; nTick++)
+ rTicks[nTick] = aOldTicks[nInvisibleAtLowerBorder+nTick];
+ }
+ }
+
+ //fill return value
+ rAllTickInfos.resize(aAllTicks.getLength());
+ for( nDepth=0 ;nDepth<aAllTicks.getLength(); nDepth++ )
+ {
+ sal_Int32 nCount = aAllTicks[nDepth].getLength();
+ rAllTickInfos[nDepth].resize( nCount );
+ for(sal_Int32 nN = 0; nN<nCount; nN++)
+ {
+ rAllTickInfos[nDepth][nN].fScaledTickValue = aAllTicks[nDepth][nN];
+ }
+ }
+
+ //-----------------------------------------
+ //get the transformed screen values for all tickmarks in aAllTickInfos
+ this->updateScreenValues( rAllTickInfos );
+
+ //-----------------------------------------
+ //'hide' tickmarks with identical screen values in aAllTickInfos
+ this->hideIdenticalScreenValues( rAllTickInfos );
+}
+
+void TickmarkHelper::addSubTicks( sal_Int32 nDepth, uno::Sequence< uno::Sequence< double > >& rParentTicks ) const
+{
+ TickIter aIter( rParentTicks, m_rIncrement, 0, nDepth-1 );
+ double* pfNextParentTick = aIter.firstValue();
+ if(!pfNextParentTick)
+ return;
+ double fLastParentTick = *pfNextParentTick;
+ pfNextParentTick = aIter.nextValue();
+ if(!pfNextParentTick)
+ return;
+
+ sal_Int32 nMaxSubTickCount = this->getMaxTickCount( nDepth );
+ if(!nMaxSubTickCount)
+ return;
+
+ uno::Sequence< double > aSubTicks(nMaxSubTickCount);
+ sal_Int32 nRealSubTickCount = 0;
+ sal_Int32 nIntervalCount = m_rIncrement.SubIncrements[nDepth-1].IntervalCount;
+
+ double* pValue = NULL;
+ for(; pfNextParentTick; fLastParentTick=*pfNextParentTick, pfNextParentTick = aIter.nextValue())
+ {
+ for( sal_Int32 nPartTick = 1; nPartTick<nIntervalCount; nPartTick++ )
+ {
+ pValue = this->getMinorTick( nPartTick, nDepth
+ , fLastParentTick, *pfNextParentTick );
+ if(!pValue)
+ continue;
+
+ aSubTicks[nRealSubTickCount] = *pValue;
+ nRealSubTickCount++;
+ }
+ }
+
+ aSubTicks.realloc(nRealSubTickCount);
+ rParentTicks[nDepth] = aSubTicks;
+ if(m_rIncrement.SubIncrements.getLength()>nDepth)
+ addSubTicks( nDepth+1, rParentTicks );
+}
+
+//-----------------------------------------------------------------------------
+// ___TickmarkHelper_3D___
+//-----------------------------------------------------------------------------
+TickmarkHelper_2D::TickmarkHelper_2D(
+ const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement
+ , double fStrech_SceneToScreen, double fOffset_SceneToScreen )
+ : TickmarkHelper( rScale, rIncrement )
+ , m_fStrech_LogicToScreen(1.0)
+ , m_fOffset_LogicToScreen(0.0)
+{
+ double fWidthY = m_fScaledVisibleMax - m_fScaledVisibleMin;
+ m_fStrech_LogicToScreen = FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY * fStrech_SceneToScreen;
+ m_fOffset_LogicToScreen = -m_fScaledVisibleMin*m_fStrech_LogicToScreen + fOffset_SceneToScreen;
+}
+
+TickmarkHelper_2D::~TickmarkHelper_2D()
+{
+}
+
+sal_Int32 TickmarkHelper_2D::transformScaledLogicTickToScreen( double fValue ) const
+{
+ sal_Int32 nRet = static_cast<sal_Int32>(
+ fValue*m_fStrech_LogicToScreen + m_fOffset_LogicToScreen);
+ return nRet;
+}
+
+//static
+sal_Int32 TickmarkHelper_2D::getTickScreenDistance( TickIter& rIter )
+{
+ //return the positive distance between the two first tickmarks in screen values
+ //if there are less than two tickmarks -1 is returned
+
+ const TickInfo* pFirstTickInfo = rIter.firstInfo();
+ const TickInfo* pSecondTickInfo = rIter.nextInfo();
+ if(!pSecondTickInfo || !pFirstTickInfo)
+ return -1;
+
+ sal_Int32 nRet = pSecondTickInfo->nScreenTickValue - pFirstTickInfo->nScreenTickValue;
+ if(nRet<0)
+ nRet *= -1;
+ return nRet;
+}
+
+sal_Int32 TickmarkHelper_2D::getScreenValueForMinimum() const
+{
+ //return the screen value at the end of the axis where the scale has its minimum
+ //(lower end of axis line)
+ return this->transformScaledLogicTickToScreen(
+ m_fScaledVisibleMin );
+}
+
+sal_Int32 TickmarkHelper_2D::getScreenValueForMaximum() const
+{
+ //return the screen value at the end of the axis where the scale has its maximum
+ //(upper end of axis line)
+ return this->transformScaledLogicTickToScreen(
+ m_fScaledVisibleMax );
+}
+
+void TickmarkHelper_2D::updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
+{
+ //get the transformed screen values for all tickmarks in rAllTickInfos
+ ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = rAllTickInfos.begin();
+ const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = rAllTickInfos.end();
+ for( ; aDepthIter != aDepthEnd; aDepthIter++ )
+ {
+ ::std::vector< TickInfo >::iterator aTickIter = (*aDepthIter).begin();
+ const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
+ for( ; aTickIter != aTickEnd; aTickIter++ )
+ {
+ TickInfo& rTickInfo = (*aTickIter);
+ rTickInfo.nScreenTickValue =
+ this->transformScaledLogicTickToScreen(
+ rTickInfo.fScaledTickValue );
+ }
+ }
+}
+
+//'hide' tickmarks with identical screen values in aAllTickInfos
+void TickmarkHelper_2D::hideIdenticalScreenValues(
+ ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
+{
+ TickIter aIter( rAllTickInfos, m_rIncrement );
+
+ TickInfo* pPreviousTickInfo = aIter.firstInfo();
+ if(!pPreviousTickInfo)
+ return;
+ pPreviousTickInfo->bPaintIt = true;
+ for( TickInfo* pTickInfo = aIter.nextInfo(); pTickInfo; pTickInfo = aIter.nextInfo())
+ {
+ pTickInfo->bPaintIt = pTickInfo->nScreenTickValue != pPreviousTickInfo->nScreenTickValue;
+ pPreviousTickInfo = pTickInfo;
+ }
+}
+//-----------------------------------------------------------------------------
+// ___TickmarkHelper_3D___
+//-----------------------------------------------------------------------------
+TickmarkHelper_3D::TickmarkHelper_3D(
+ const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement )
+ : TickmarkHelper( rScale, rIncrement )
+{
+}
+
+TickmarkHelper_3D::~TickmarkHelper_3D()
+{
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/view/axes/TickmarkHelper.hxx b/chart2/source/view/axes/TickmarkHelper.hxx
new file mode 100644
index 000000000000..1462cc8dcb5c
--- /dev/null
+++ b/chart2/source/view/axes/TickmarkHelper.hxx
@@ -0,0 +1,265 @@
+/*************************************************************************
+ *
+ * $RCSfile: TickmarkHelper.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2003 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#ifndef _CHART2_TICKMARKHELPER_HXX
+#define _CHART2_TICKMARKHELPER_HXX
+
+#include <vector>
+
+#ifndef _DRAFTS_COM_SUN_STAR_CHART2_EXPLICITINCREMENTDATA_HPP_
+#include <drafts/com/sun/star/chart2/ExplicitIncrementData.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_CHART2_EXPLICITSCALEDATA_HPP_
+#include <drafts/com/sun/star/chart2/ExplicitScaleData.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_DRAWING_XSHAPE_HPP_
+#include <com/sun/star/drawing/XShape.hpp>
+#endif
+#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
+#include <com/sun/star/uno/Sequence.h>
+#endif
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+
+//-----------------------------------------------------------------------------
+/**
+*/
+
+struct TickInfo
+{
+ double fScaledTickValue;
+ double fUnscaledTickValue;
+
+ sal_Int32 nScreenTickValue;
+
+ bool bPaintIt;
+
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::drawing::XShape > xTextShape;
+
+//methods:
+ TickInfo();
+ void updateUnscaledValue( const ::com::sun::star::uno::Reference<
+ ::drafts::com::sun::star::chart2::XScaling >& xInverseScaling );
+};
+
+class TickIter
+{
+public:
+ TickIter( const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Sequence< double > >& rTicks
+ , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement
+ , sal_Int32 nMinDepth=0, sal_Int32 nMaxDepth=-1 );
+ TickIter( ::std::vector< ::std::vector< TickInfo > >& rTickInfos
+ , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement
+ , sal_Int32 nMinDepth=0, sal_Int32 nMaxDepth=-1 );
+ virtual ~TickIter();
+
+ double* firstValue();
+ double* nextValue();
+
+ TickInfo* firstInfo();
+ TickInfo* nextInfo();
+
+ sal_Int32 getCurrentDepth() const { return m_nCurrentDepth; }
+
+private: //methods
+ sal_Int32 getIntervalCount( sal_Int32 nDepth );
+ bool isAtLastPartTick();
+
+ void initIter( sal_Int32 nMinDepth, sal_Int32 nMaxDepth );
+ sal_Int32 getStartDepth() const;
+
+ bool gotoFirst();
+ bool gotoNext();
+
+
+ double _getTickValue(sal_Int32 nDepth, sal_Int32 nIndex) const
+ {
+ if(m_pSimpleTicks)
+ return (*m_pSimpleTicks)[nDepth][nIndex];
+ else
+ return (((*m_pInfoTicks)[nDepth])[nIndex]).fScaledTickValue;
+ }
+ sal_Int32 _getTickCount( sal_Int32 nDepth ) const
+ {
+ if(m_pSimpleTicks)
+ return (*m_pSimpleTicks)[nDepth].getLength();
+ else
+ return (*m_pInfoTicks)[nDepth].size();
+ }
+ sal_Int32 _getMaxDepth() const
+ {
+ if(m_pSimpleTicks)
+ return (*m_pSimpleTicks).getLength()-1;
+ else
+ return (*m_pInfoTicks).size()-1;
+ }
+
+private: //member
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Sequence< double > >* m_pSimpleTicks;
+ ::std::vector< ::std::vector< TickInfo > >* m_pInfoTicks;
+ const ::drafts::com::sun::star::chart2::ExplicitIncrementData& m_rIncrement;
+ //iteration from m_nMinDepth to m_nMaxDepth
+ sal_Int32 m_nMinDepth;
+ sal_Int32 m_nMaxDepth;
+ sal_Int32 m_nTickCount;
+ sal_Int32* m_pnPositions; //current positions in the different sequences
+ sal_Int32* m_pnPreParentCount; //the tickmarks do not start with a major tick always,
+ //the PreParentCount states for each depth how many subtickmarks are available in front of the first parent tickmark
+ bool* m_pbIntervalFinished;
+ sal_Int32 m_nCurrentDepth;
+ sal_Int32 m_nCurrentPos;
+ double m_fCurrentValue;
+};
+
+class TickmarkHelper
+{
+public:
+ TickmarkHelper(
+ const ::drafts::com::sun::star::chart2::ExplicitScaleData& rScale
+ , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement );
+ virtual ~TickmarkHelper();
+
+ void getAllTicks( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const;
+ bool isPostEquidistant( sal_Int32 nDepth ) const;
+
+ //
+ static double getMinimumAtIncrement( double fMin, const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement );
+ static double getMaximumAtIncrement( double fMax, const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement );
+
+protected: //methods
+ void addSubTicks( sal_Int32 nDepth,
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Sequence< double > >& rParentTicks ) const;
+ double* getMajorTick( sal_Int32 nTick ) const;
+ double* getMinorTick( sal_Int32 nTick, sal_Int32 nDepth
+ , double fStartParentTick, double fNextParentTick ) const;
+ sal_Int32 getMaxTickCount( sal_Int32 nDepth = 0 ) const;
+ sal_Int32 getTickDepth() const;
+ bool isVisible( double fValue ) const;
+ bool isWithinOuterBorder( double fScaledValue ) const; //all within the outer major tick marks
+
+ virtual void updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const {}
+ virtual void hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const {}
+
+protected: //member
+ const ::drafts::com::sun::star::chart2::ExplicitScaleData& m_rScale;
+ const ::drafts::com::sun::star::chart2::ExplicitIncrementData& m_rIncrement;
+
+ ::com::sun::star::uno::Reference< ::drafts::com::sun::star::chart2::XScaling >
+ m_xInverseScaling;
+ double* m_pfCurrentValues;
+ //major-tick positions that may lay outside the visible range but complete partly visible intervals at the borders
+ double m_fOuterMajorTickBorderMin;
+ double m_fOuterMajorTickBorderMax;
+ double m_fOuterMajorTickBorderMin_Scaled;
+ double m_fOuterMajorTickBorderMax_Scaled;
+
+ //minimum and maximum of the visible range after scaling
+ double m_fScaledVisibleMin;
+ double m_fScaledVisibleMax;
+};
+
+class TickmarkHelper_2D : public TickmarkHelper
+{
+public:
+ TickmarkHelper_2D(
+ const ::drafts::com::sun::star::chart2::ExplicitScaleData& rScale
+ , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement
+ , double fStrech_SceneToScreen, double fOffset_SceneToScreen );
+ virtual ~TickmarkHelper_2D();
+
+ static sal_Int32 getTickScreenDistance( TickIter& rIter );
+
+ //methods more for axis line
+ sal_Int32 getScreenValueForMinimum() const;
+ sal_Int32 getScreenValueForMaximum() const;
+
+protected: //methods
+ virtual void updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const;
+ virtual void hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const;
+
+ sal_Int32 transformScaledLogicTickToScreen( double fValue ) const;
+
+private: //member
+ double m_fStrech_LogicToScreen;
+ double m_fOffset_LogicToScreen;
+};
+
+class TickmarkHelper_3D : public TickmarkHelper
+{
+public:
+ TickmarkHelper_3D(
+ const ::drafts::com::sun::star::chart2::ExplicitScaleData& rScale
+ , const ::drafts::com::sun::star::chart2::ExplicitIncrementData& rIncrement );
+ virtual ~TickmarkHelper_3D();
+
+};
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
+#endif
diff --git a/chart2/source/view/axes/VAxisProperties.cxx b/chart2/source/view/axes/VAxisProperties.cxx
new file mode 100644
index 000000000000..b94493b16524
--- /dev/null
+++ b/chart2/source/view/axes/VAxisProperties.cxx
@@ -0,0 +1,468 @@
+/*************************************************************************
+ *
+ * $RCSfile: VAxisProperties.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2003 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include "VAxisProperties.hxx"
+#include "macros.hxx"
+#include "ViewDefines.hxx"
+#include "CommonConverters.hxx"
+
+#ifndef _TOOLS_COLOR_HXX
+#include <tools/color.hxx>
+#endif
+
+#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+#ifndef _COM_SUN_STAR_CHART_CHARTAXISARRANGEORDERTYPE_HPP_
+#include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
+#endif
+#ifndef _COM_SUN_STAR_DRAWING_LINESTYLE_HPP_
+#include <com/sun/star/drawing/LineStyle.hpp>
+#endif
+#ifndef _COM_SUN_STAR_TEXT_WRITINGMODE2_HPP_
+#include <com/sun/star/text/WritingMode2.hpp>
+#endif
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::drafts::com::sun::star::chart2;
+
+sal_Int32 AxisProperties::calcTickLengthForDepth(sal_Int32 nDepth,sal_Int32 nTickmarkStyle) const
+{
+ sal_Int32 nWidth = AXIS2D_TICKLENGTH; //@maybefuturetodo this length could be offered by the model
+ double fPercent = 1.0;
+ switch(nDepth)
+ {
+ case 0:
+ fPercent = 1.0;
+ break;
+ case 1:
+ fPercent = 0.75;//percentage like in the old chart
+ break;
+ case 2:
+ fPercent = 0.5;
+ break;
+ default:
+ fPercent = 0.3;
+ break;
+ }
+ if(nTickmarkStyle==3)//inner and outer tickmarks
+ fPercent*=2.0;
+ return static_cast<sal_Int32>(nWidth*fPercent);
+}
+
+sal_Int32 getTickOffset(sal_Int32 nLength,sal_Int32 nTickmarkStyle)
+{
+ double fPercent = 0.0; //0<=fPercent<=1
+ //0.0: completly inner
+ //1.0: completly outer
+ //0.5: half and half
+
+ /*
+ nTickmarkStyle:
+ 1: inner tickmarks
+ 2: outer tickmarks
+ 3: inner and outer tickmarks
+ */
+ switch(nTickmarkStyle)
+ {
+ case 1:
+ fPercent = 0.0;
+ break;
+ case 2:
+ fPercent = 1.0;
+ break;
+ default:
+ fPercent = 0.5;
+ break;
+ }
+ return static_cast<sal_Int32>(fPercent*nLength);
+}
+
+LineProperties AxisProperties::makeLinePropertiesForDepth( sal_Int32 nDepth ) const
+{
+ //@todo get this from somewhere; maybe for each subincrement
+ //so far the model does not offer different settings for each tick depth
+ return m_aLineProperties;
+}
+
+TickmarkProperties AxisProperties::makeTickmarkProperties(
+ sal_Int32 nDepth ) const
+{
+ /*
+ nTickmarkStyle:
+ 1: inner tickmarks
+ 2: outer tickmarks
+ 3: inner and outer tickmarks
+ */
+ sal_Int32 nTickmarkStyle = 1;
+ if(nDepth==0)
+ {
+ nTickmarkStyle = m_nMajorTickmarks;
+ if(!nTickmarkStyle)
+ {
+ //create major tickmarks as if they were minor tickmarks
+ nDepth = 1;
+ nTickmarkStyle = m_nMinorTickmarks;
+ }
+ }
+ else if( nDepth==1)
+ {
+ nTickmarkStyle = m_nMinorTickmarks;
+ }
+
+ TickmarkProperties aTickmarkProperties;
+ aTickmarkProperties.Length = this->calcTickLengthForDepth(nDepth,nTickmarkStyle);
+
+ sal_Int32 nSign = m_bIsLeftOrBottomAxis ? 1 : -1;
+ if(m_bIsYAxis)
+ nSign *= -1;
+ aTickmarkProperties.RelativePos = nSign*getTickOffset(aTickmarkProperties.Length,nTickmarkStyle);
+ aTickmarkProperties.Length *= -nSign;
+ aTickmarkProperties.aLineProperties = this->makeLinePropertiesForDepth( nDepth );
+ return aTickmarkProperties;
+}
+
+//--------------------------------------------------------------------------
+
+AxisProperties::AxisProperties()
+ : m_xAxisModel(NULL)
+ , m_bIsYAxis(true)
+ , m_bIsLeftOrBottomAxis(true)
+ , m_pfMainLinePositionAtOtherAxis(NULL)
+ , m_pfExrtaLinePositionAtOtherAxis(NULL)
+ /*
+ , m_nOrthogonalAxisScreenPosition(0)
+ , m_nOrthogonalAxisExtraLineScreenPosition(0)
+ */
+ , m_eRelativeLabelPosition(LEFTORBOTTOM_OF_AXIS)
+ , m_nMajorTickmarks(1)
+ , m_nMinorTickmarks(1)
+ , m_aTickmarkPropertiesList()
+ , m_aLineProperties()
+ , m_bTESTTEST_HorizontalAdjustmentIsLeft(true)
+{
+}
+
+AxisProperties::AxisProperties( const AxisProperties& rAxisProperties )
+ : m_xAxisModel( rAxisProperties.m_xAxisModel )
+ , m_bIsYAxis( rAxisProperties.m_bIsYAxis )
+ , m_bIsLeftOrBottomAxis( rAxisProperties.m_bIsLeftOrBottomAxis )
+ , m_pfMainLinePositionAtOtherAxis( NULL )
+ , m_pfExrtaLinePositionAtOtherAxis( NULL )
+ , m_eRelativeLabelPosition( rAxisProperties.m_eRelativeLabelPosition )
+ , m_nMajorTickmarks( rAxisProperties.m_nMajorTickmarks )
+ , m_nMinorTickmarks( rAxisProperties.m_nMinorTickmarks )
+ , m_aTickmarkPropertiesList( rAxisProperties.m_aTickmarkPropertiesList )
+ , m_aLineProperties( rAxisProperties.m_aLineProperties )
+ , m_bTESTTEST_HorizontalAdjustmentIsLeft( rAxisProperties.m_bTESTTEST_HorizontalAdjustmentIsLeft )
+{
+ if( rAxisProperties.m_pfMainLinePositionAtOtherAxis )
+ m_pfMainLinePositionAtOtherAxis = new double(*rAxisProperties.m_pfMainLinePositionAtOtherAxis);
+ if( rAxisProperties.m_pfExrtaLinePositionAtOtherAxis )
+ m_pfExrtaLinePositionAtOtherAxis = new double (*rAxisProperties.m_pfExrtaLinePositionAtOtherAxis);
+}
+
+AxisProperties::~AxisProperties()
+{
+ delete m_pfMainLinePositionAtOtherAxis;
+ delete m_pfExrtaLinePositionAtOtherAxis;
+}
+
+void AxisProperties::init()
+{
+ if( !m_xAxisModel.is() )
+ return;
+ sal_Int32 nDimension = m_xAxisModel->getRepresentedDimension();
+ m_bIsYAxis = (nDimension==1);
+
+ //init LineProperties
+ m_aLineProperties.initFromPropertySet( uno::Reference<beans::XPropertySet>::query( m_xAxisModel ) );
+
+ //init TickmarkProperties
+ uno::Reference< beans::XPropertySet > xProp =
+ uno::Reference<beans::XPropertySet>::query( this->m_xAxisModel );
+ if(xProp.is())
+ {
+ try
+ {
+ xProp->getPropertyValue( C2U( "MajorTickmarks" ) ) >>= m_nMajorTickmarks;
+ xProp->getPropertyValue( C2U( "MinorTickmarks" ) ) >>= m_nMinorTickmarks;
+
+ sal_Int32 nMaxDepth = 0;
+ if(m_nMinorTickmarks!=0)
+ nMaxDepth=2;
+ else if(m_nMajorTickmarks!=0)
+ nMaxDepth=1;
+
+ this->m_aTickmarkPropertiesList.clear();
+ for( sal_Int32 nDepth=0; nDepth<nMaxDepth; nDepth++ )
+ {
+ TickmarkProperties aTickmarkProperties = this->makeTickmarkProperties( nDepth );
+ this->m_aTickmarkPropertiesList.push_back( aTickmarkProperties );
+ }
+ }
+ catch( uno::Exception& e )
+ {
+ e;
+ }
+ }
+}
+
+sal_Int32 getAxisScreenPosition( double fCrossOtherAxis
+ , const PlottingPositionHelper& rPosHelper, bool bIsYAxis )
+{
+ double fX = bIsYAxis ? fCrossOtherAxis : rPosHelper.getLogicMinX();
+ double fY = bIsYAxis ? rPosHelper.getLogicMinY() : fCrossOtherAxis;
+
+ rPosHelper.clipLogicValues( &fX,&fY,0 );
+ rPosHelper.doLogicScaling( &fX,&fY,0 );
+ drawing::Position3D aPos( fX, fY, 0);
+
+ uno::Reference< XTransformation > xTransformation =
+ rPosHelper.getTransformationLogicToScene();
+ uno::Sequence< double > aSeq =
+ xTransformation->transform( Position3DToSequence(aPos) );
+
+ return static_cast<sal_Int32>(
+ bIsYAxis ? aSeq[0] : aSeq[1] );
+}
+
+
+
+sal_Int32 AxisProperties::getMainLineScreenPosition(
+ const PlottingPositionHelper& rPosHelper ) const
+{
+ double fMin = m_bIsYAxis ? rPosHelper.getLogicMinX() : rPosHelper.getLogicMinY();
+ double fMax = m_bIsYAxis ? rPosHelper.getLogicMaxX() : rPosHelper.getLogicMaxY();
+
+ double fCrossOtherAxis;
+ if(m_pfMainLinePositionAtOtherAxis)
+ fCrossOtherAxis = *m_pfMainLinePositionAtOtherAxis;
+ else
+ fCrossOtherAxis = m_bIsLeftOrBottomAxis ? fMin : fMax;
+ sal_Int32 nRet = getAxisScreenPosition( fCrossOtherAxis, rPosHelper, m_bIsYAxis );
+ return nRet;
+}
+
+bool AxisProperties::getExtraLineScreenPosition(
+ sal_Int32& rnExtraLineScreenPosition, const PlottingPositionHelper& rPosHelper ) const
+{
+ if( !m_pfExrtaLinePositionAtOtherAxis )
+ return false;
+
+ double fMin = m_bIsYAxis ? rPosHelper.getLogicMinX() : rPosHelper.getLogicMinY();
+ double fMax = m_bIsYAxis ? rPosHelper.getLogicMaxX() : rPosHelper.getLogicMaxY();
+ if( *m_pfExrtaLinePositionAtOtherAxis <= fMin
+ || *m_pfExrtaLinePositionAtOtherAxis >= fMax )
+ return false;
+ rnExtraLineScreenPosition = getAxisScreenPosition(
+ *m_pfExrtaLinePositionAtOtherAxis, rPosHelper, m_bIsYAxis );
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+
+AxisLabelProperties::AxisLabelProperties()
+ : aNumberFormat()
+ , bDisplayLabels( true )
+ , eStaggering( SIDE_BY_SIDE )
+ , bLineBreakAllowed( true )
+ , bOverlapAllowed( false )
+ , bStackCharacters( false )
+ , fRotationAngleDegree( 0.0 )
+ , nRhythm( 1 )
+ , bRhythmIsFix(false)
+{
+ /*
+ aLocale.Language = C2U( "en" );
+ aLocale.Country = C2U( "US" );
+
+ //aLocale.Language = C2U( "ar" );
+ //aLocale.Country = C2U( "IR" );
+
+ //aLocale.Language = C2U( "ja" );
+ //aLocale.Country = C2U( "JP" );
+ */
+}
+
+void AxisLabelProperties::init( const uno::Reference< XAxis >& xAxisModel )
+{
+ uno::Reference< beans::XPropertySet > xProp =
+ uno::Reference<beans::XPropertySet>::query( xAxisModel );
+ if(xProp.is())
+ {
+ try
+ {
+ if( !( xProp->getPropertyValue( C2U( "NumberFormat" ) ) >>= this->aNumberFormat ) )
+ {
+ //@todo get number format from calc
+ }
+
+ xProp->getPropertyValue( C2U( "DisplayLabels" ) ) >>= this->bDisplayLabels;
+ xProp->getPropertyValue( C2U( "TextBreak" ) ) >>= this->bLineBreakAllowed;
+ xProp->getPropertyValue( C2U( "TextOverlap" ) ) >>= this->bOverlapAllowed;
+ xProp->getPropertyValue( C2U( "StackCharacters" ) ) >>= this->bStackCharacters;
+ xProp->getPropertyValue( C2U( "TextRotation" ) ) >>= this->fRotationAngleDegree;
+
+ ::com::sun::star::chart::ChartAxisArrangeOrderType eArrangeOrder;
+ xProp->getPropertyValue( C2U( "ArrangeOrder" ) ) >>= eArrangeOrder;
+ switch(eArrangeOrder)
+ {
+ case ::com::sun::star::chart::ChartAxisArrangeOrderType_SIDE_BY_SIDE:
+ this->eStaggering = SIDE_BY_SIDE;
+ break;
+ case ::com::sun::star::chart::ChartAxisArrangeOrderType_STAGGER_EVEN:
+ this->eStaggering = STAGGER_EVEN;
+ break;
+ case ::com::sun::star::chart::ChartAxisArrangeOrderType_STAGGER_ODD:
+ this->eStaggering = STAGGER_ODD;
+ break;
+ default:
+ this->eStaggering = STAGGER_AUTO;
+ break;
+ }
+ }
+ catch( uno::Exception& e )
+ {
+ e;
+ }
+ }
+}
+
+/*
+sal_Int16 getSwappedWritingMode( sal_Int16 nWritingMode )
+{
+ //LR_TB == LT
+ //RL_TB == RT (Arabic, Hebrew)
+ //TB_RL == TR (Japanese, Chinese, Korean)
+ // ?? TL (Mongolian) see also text::WritingMode2
+
+ switch(nWritingMode)
+ {
+ case text::WritingMode2::RL_TB:
+ return text::WritingMode2::TB_RL;
+ case text::WritingMode2::TB_RL:
+ return text::WritingMode2::RL_TB;
+ case text::WritingMode2::LR_TB:
+ return text::WritingMode2::TB_LR;
+ default:
+ return text::WritingMode2::LR_TB;
+ }
+}
+*/
+
+sal_Bool AxisLabelProperties::getIsStaggered() const
+{
+ if( STAGGER_ODD == eStaggering || STAGGER_EVEN == eStaggering )
+ return sal_True;
+ return sal_False;
+}
+
+//------------------------
+
+drawing::TextVerticalAdjust AxisProperties::getVerticalAdjustment() const
+{
+ drawing::TextVerticalAdjust aRet =
+ !m_bIsYAxis && !m_bIsLeftOrBottomAxis
+ ? drawing::TextVerticalAdjust_BOTTOM
+ : drawing::TextVerticalAdjust_TOP;
+ return aRet;
+}
+
+sal_Int16 AxisProperties::getWritingMode()const
+{
+ //@todo get this dependent on the locale ...
+ sal_Int16 nWritingMode( text::WritingMode2::LR_TB );
+ return nWritingMode;
+}
+
+drawing::TextHorizontalAdjust AxisProperties::getHorizontalAdjustment() const
+{
+ return m_bTESTTEST_HorizontalAdjustmentIsLeft
+ ? drawing::TextHorizontalAdjust_LEFT
+ : drawing::TextHorizontalAdjust_RIGHT;
+//
+
+ bool bIsYAxis = m_bIsYAxis;
+ bool bIsLeftOrBottomAxis = m_bIsLeftOrBottomAxis;
+ sal_Int16 nWritingMode = getWritingMode();
+
+ switch( nWritingMode )
+ {
+ case text::WritingMode2::RL_TB:
+ case text::WritingMode2::TB_RL:
+ return bIsYAxis && !bIsLeftOrBottomAxis
+ ? drawing::TextHorizontalAdjust_LEFT
+ : drawing::TextHorizontalAdjust_RIGHT;
+ case text::WritingMode2::TB_LR:
+ default:
+ return bIsYAxis && bIsLeftOrBottomAxis
+ ? drawing::TextHorizontalAdjust_RIGHT
+ : drawing::TextHorizontalAdjust_LEFT;
+ }
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/view/axes/VCoordinateSystem.cxx b/chart2/source/view/axes/VCoordinateSystem.cxx
new file mode 100644
index 000000000000..dc9c9e08cc6d
--- /dev/null
+++ b/chart2/source/view/axes/VCoordinateSystem.cxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * $RCSfile: VCoordinateSystem.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2003 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+#include "VCoordinateSystem.hxx"
+#include "ScaleAutomatism.hxx"
+#include "VSeriesPlotter.hxx"
+#include "VGrid.hxx"
+
+//.............................................................................
+namespace chart
+{
+//.............................................................................
+using namespace ::com::sun::star;
+using namespace ::drafts::com::sun::star::chart2;
+
+VCoordinateSystem::VCoordinateSystem( const uno::Reference< XBoundedCoordinateSystem >& xCooSys )
+ : m_xCooSysModel(xCooSys)
+ , m_xAxis0(NULL)
+ , m_xAxis1(NULL)
+ , m_xAxis2(NULL)
+ , m_xGridList0()
+ , m_xGridList1()
+ , m_xGridList2()
+ , m_aExplicitScales(3)
+ , m_aExplicitIncrements(3)
+{
+}
+VCoordinateSystem::~VCoordinateSystem()
+{
+
+}
+
+void VCoordinateSystem::setOrigin( double* fCoordinateOrigin )
+{
+ m_fCoordinateOrigin[0]=fCoordinateOrigin[0];
+ m_fCoordinateOrigin[1]=fCoordinateOrigin[1];
+ m_fCoordinateOrigin[2]=fCoordinateOrigin[2];
+}
+
+uno::Reference< XBoundedCoordinateSystem > VCoordinateSystem::getModel() const
+{
+ return m_xCooSysModel;
+}
+
+void VCoordinateSystem::addAxis( const uno::Reference< XAxis >& xAxis )
+{
+ if(!xAxis.is())
+ return;
+ sal_Int32 nDim = xAxis->getRepresentedDimension();
+ if(0==nDim)
+ m_xAxis0 = xAxis;
+ else if(1==nDim)
+ m_xAxis1 = xAxis;
+ else if(2==nDim)
+ m_xAxis2 = xAxis;
+}
+
+uno::Sequence< uno::Reference< XGrid > >& VCoordinateSystem::getGridListByDimension( sal_Int32 nDim )
+{
+ if( 0==nDim )
+ return m_xGridList0;
+ if( 1==nDim )
+ return m_xGridList1;
+ return m_xGridList2;
+}
+
+void VCoordinateSystem::addGrid( const uno::Reference< XGrid >& xGrid )
+{
+ if(!xGrid.is())
+ return;
+ sal_Int32 nDim = xGrid->getRepresentedDimension();
+ uno::Sequence< uno::Reference< XGrid > >& rGridList
+ = getGridListByDimension( nDim );
+
+ rGridList.realloc(rGridList.getLength()+1);
+ rGridList[rGridList.getLength()-1] = xGrid;
+}
+
+void VCoordinateSystem::createGridShapes(
+ const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory
+ , const uno::Reference< drawing::XShapes >& xTarget
+ , const drawing::HomogenMatrix& rHM_SceneToScreen )
+{
+ sal_Int32 nDimensionCount = m_xCooSysModel->getDimension();
+ for( sal_Int32 nDim=0; nDim<3; nDim++)
+ {
+ uno::Sequence< uno::Reference< XGrid > >& rGridList
+ = getGridListByDimension( nDim );
+ for( sal_Int32 nN=0; nN<rGridList.getLength(); nN++ )
+ {
+ VGrid aGrid(rGridList[nN],nDimensionCount);
+ aGrid.setMeterData( m_aExplicitScales[nDim], m_aExplicitIncrements[nDim] );
+
+ aGrid.init(xTarget,xTarget,xShapeFactory);
+ if(2==nDimensionCount)
+ aGrid.setTransformationSceneToScreen( rHM_SceneToScreen );
+ aGrid.setScales( m_aExplicitScales );
+ aGrid.createShapes();
+ }
+ }
+}
+
+uno::Reference< XAxis > VCoordinateSystem::getAxisByDimension( sal_Int32 nDim ) const
+{
+ uno::Reference< XAxis > xAxis(NULL);
+ if(0==nDim)
+ xAxis = m_xAxis0;
+ else if(1==nDim)
+ xAxis = m_xAxis1;
+ else if(2==nDim)
+ xAxis = m_xAxis2;
+ return xAxis;
+}
+
+void setExplicitScaleToDefault( ExplicitScaleData& rExplicitScale )
+{
+ rExplicitScale.Minimum = 0.0;
+ rExplicitScale.Maximum = 1.0;
+ rExplicitScale.Orientation = AxisOrientation_MATHEMATICAL;
+ //rExplicitScale.Scaling = ;
+ //rExplicitScale.Breaks = ;
+}
+
+void VCoordinateSystem::doAutoScale( MinimumAndMaximumSupplier* pMinMaxSupplier )
+{
+ for( sal_Int32 nDim = 0; nDim < 2; nDim++ )
+ {
+ if(nDim < 0 || nDim > 2 )
+ return;
+
+ uno::Reference< XScale > xScale(
+ m_xCooSysModel->getScaleByDimension( nDim ),
+ uno::UNO_QUERY );
+ if( ! xScale.is() )
+ return;
+ ScaleAutomatism aScaleAutomatism( xScale->getScaleData() );
+ uno::Reference< XAxis > xAxis( this->getAxisByDimension(nDim) );
+ if(xAxis.is())
+ {
+ uno::Reference< XIncrement > xInc( xAxis->getIncrement() );
+ if( xInc.is() )
+ {
+ aScaleAutomatism.m_aSourceIncrement = xInc->getIncrementData();
+ aScaleAutomatism.m_aSourceSubIncrementList = xInc->getSubIncrements();
+ }
+ }
+ if(0==nDim)
+ {
+ aScaleAutomatism.m_fValueMinimum = pMinMaxSupplier->getMinimumX();
+ aScaleAutomatism.m_fValueMaximum = pMinMaxSupplier->getMaximumX();
+ }
+ else if(1==nDim)
+ {
+ const ExplicitScaleData& rScale = m_aExplicitScales[0];
+ //@todo iterate through all xSlots which belong to coordinate system dimension in this plotter
+ //and iterate through all plotter for this coordinate system dimension
+ sal_Int32 nXSlotIndex = 0;
+ aScaleAutomatism.m_fValueMinimum = pMinMaxSupplier->getMinimumYInRange(rScale.Minimum,rScale.Maximum);
+ aScaleAutomatism.m_fValueMaximum = pMinMaxSupplier->getMaximumYInRange(rScale.Minimum,rScale.Maximum);
+ }
+ aScaleAutomatism.calculateExplicitScaleAndIncrement(
+ m_aExplicitScales[nDim], m_aExplicitIncrements[nDim] );
+ }
+ setExplicitScaleToDefault(m_aExplicitScales[2]);
+}
+
+//.............................................................................
+} //namespace chart
+//.............................................................................
diff --git a/chart2/source/view/axes/makefile.mk b/chart2/source/view/axes/makefile.mk
new file mode 100644
index 000000000000..dd0fac9cff24
--- /dev/null
+++ b/chart2/source/view/axes/makefile.mk
@@ -0,0 +1,91 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: bm $ $Date: 2003-10-06 09:58:33 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ= ..$/..$/..
+PRJINC= $(PRJ)$/source
+PRJNAME= chart2
+TARGET= chvaxes
+
+ENABLE_EXCEPTIONS= TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE: settings.mk
+#.IF "$(GUI)" == "WNT"
+#CFLAGS+=-GR
+#.ENDIF
+
+# --- export library -------------------------------------------------
+
+#object files to build and link together to lib $(SLB)$/$(TARGET).lib
+SLOFILES = \
+ $(SLO)$/VMeterBase.obj \
+ $(SLO)$/TickmarkHelper.obj \
+ $(SLO)$/ScaleAutomatism.obj \
+ $(SLO)$/VCoordinateSystem.obj \
+ $(SLO)$/VAxisProperties.obj \
+ $(SLO)$/VAxis.obj \
+ $(SLO)$/VGrid.obj
+
+# --- Targets -----------------------------------------------------------------
+
+.INCLUDE: target.mk