LCOV - code coverage report
Current view: top level - chart2/source/view/axes - VCartesianAxis.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 547 832 65.7 %
Date: 2012-08-25 Functions: 40 48 83.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 571 1306 43.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include <basegfx/numeric/ftools.hxx>
      21                 :            : 
      22                 :            : #include "VCartesianAxis.hxx"
      23                 :            : #include "PlottingPositionHelper.hxx"
      24                 :            : #include "ShapeFactory.hxx"
      25                 :            : #include "CommonConverters.hxx"
      26                 :            : #include "macros.hxx"
      27                 :            : #include "ViewDefines.hxx"
      28                 :            : #include "PropertyMapper.hxx"
      29                 :            : #include "NumberFormatterWrapper.hxx"
      30                 :            : #include "LabelPositionHelper.hxx"
      31                 :            : #include "TrueGuard.hxx"
      32                 :            : #include "BaseGFXHelper.hxx"
      33                 :            : #include "AxisHelper.hxx"
      34                 :            : #include "Tickmarks_Equidistant.hxx"
      35                 :            : 
      36                 :            : #include <rtl/math.hxx>
      37                 :            : #include <tools/color.hxx>
      38                 :            : #include <com/sun/star/text/XText.hpp>
      39                 :            : #include <com/sun/star/text/WritingMode2.hpp>
      40                 :            : #include <editeng/unoprnms.hxx>
      41                 :            : #include <svx/unoshape.hxx>
      42                 :            : #include <svx/unoshtxt.hxx>
      43                 :            : 
      44                 :            : #include <algorithm>
      45                 :            : #include <boost/scoped_ptr.hpp>
      46                 :            : 
      47                 :            : //.............................................................................
      48                 :            : namespace chart
      49                 :            : {
      50                 :            : //.............................................................................
      51                 :            : using namespace ::com::sun::star;
      52                 :            : using namespace ::com::sun::star::chart2;
      53                 :            : using namespace ::rtl::math;
      54                 :            : using ::com::sun::star::uno::Reference;
      55                 :            : 
      56                 :            : //-----------------------------------------------------------------------------
      57                 :            : //-----------------------------------------------------------------------------
      58                 :            : //-----------------------------------------------------------------------------
      59                 :            : 
      60                 :       1938 : VCartesianAxis::VCartesianAxis( const AxisProperties& rAxisProperties
      61                 :            :             , const Reference< util::XNumberFormatsSupplier >& xNumberFormatsSupplier
      62                 :            :             , sal_Int32 nDimensionIndex, sal_Int32 nDimensionCount
      63                 :            :             , PlottingPositionHelper* pPosHelper )//takes ownership
      64                 :       1938 :             : VAxisBase( nDimensionIndex, nDimensionCount, rAxisProperties, xNumberFormatsSupplier )
      65                 :            : {
      66         [ -  + ]:       1938 :     if( pPosHelper )
      67                 :          0 :         m_pPosHelper = pPosHelper;
      68                 :            :     else
      69 [ +  - ][ +  - ]:       1938 :         m_pPosHelper = new PlottingPositionHelper();
      70                 :       1938 : }
      71                 :            : 
      72                 :       1938 : VCartesianAxis::~VCartesianAxis()
      73                 :            : {
      74 [ +  - ][ +  - ]:       1938 :     delete m_pPosHelper;
      75                 :       1938 :     m_pPosHelper = NULL;
      76         [ -  + ]:       3876 : }
      77                 :            : 
      78                 :            : //-----------------------------------------------------------------------------
      79                 :            : //-----------------------------------------------------------------------------
      80                 :            : 
      81                 :      15951 : Reference< drawing::XShape > createSingleLabel(
      82                 :            :             const Reference< lang::XMultiServiceFactory>& xShapeFactory
      83                 :            :           , const Reference< drawing::XShapes >& xTarget
      84                 :            :           , const awt::Point& rAnchorScreenPosition2D
      85                 :            :           , const rtl::OUString& rLabel
      86                 :            :           , const AxisLabelProperties& rAxisLabelProperties
      87                 :            :           , const AxisProperties& rAxisProperties
      88                 :            :           , const tNameSequence& rPropNames
      89                 :            :           , const tAnySequence& rPropValues
      90                 :            :           )
      91                 :            : {
      92         [ +  + ]:      15951 :     if(rLabel.isEmpty())
      93         [ +  - ]:         18 :         return 0;
      94                 :            : 
      95                 :            :     // #i78696# use mathematically correct rotation now
      96                 :      15933 :     const double fRotationAnglePi(rAxisLabelProperties.fRotationAngleDegree * (F_PI / -180.0));
      97         [ +  - ]:      15933 :     uno::Any aATransformation = ShapeFactory::makeTransformation( rAnchorScreenPosition2D, fRotationAnglePi );
      98         [ +  - ]:      15933 :     rtl::OUString aLabel = ShapeFactory::getStackedString( rLabel, rAxisLabelProperties.bStackCharacters );
      99                 :            : 
     100                 :            :     Reference< drawing::XShape > xShape2DText = ShapeFactory(xShapeFactory)
     101 [ +  - ][ +  - ]:      15933 :                     .createText( xTarget, aLabel, rPropNames, rPropValues, aATransformation );
                 [ +  - ]
     102                 :            : 
     103                 :            :     //correctPositionForRotation
     104                 :            :     LabelPositionHelper::correctPositionForRotation( xShape2DText
     105         [ +  - ]:      15933 :         , rAxisProperties.m_aLabelAlignment, rAxisLabelProperties.fRotationAngleDegree, rAxisProperties.m_bComplexCategories );
     106                 :            : 
     107                 :      15951 :     return xShape2DText;
     108                 :            : }
     109                 :            : 
     110                 :       7531 : bool lcl_doesShapeOverlapWithTickmark( const Reference< drawing::XShape >& xShape
     111                 :            :                        , double fRotationAngleDegree
     112                 :            :                        , const basegfx::B2DVector& rTickScreenPosition
     113                 :            :                        , bool bIsHorizontalAxis, bool bIsVerticalAxis )
     114                 :            : {
     115         [ -  + ]:       7531 :     if(!xShape.is())
     116                 :          0 :         return false;
     117                 :            : 
     118 [ +  - ][ +  - ]:       7531 :     ::basegfx::B2IRectangle aShapeRect = BaseGFXHelper::makeRectangle(xShape->getPosition(),ShapeFactory::getSizeAfterRotation( xShape, fRotationAngleDegree ));
         [ +  - ][ +  - ]
     119                 :            : 
     120         [ +  + ]:       7531 :     if( bIsVerticalAxis )
     121                 :            :     {
     122         [ +  - ]:       4170 :         return ( (rTickScreenPosition.getY() >= aShapeRect.getMinY())
     123 [ +  + ][ +  - ]:       4170 :             && (rTickScreenPosition.getY() <= aShapeRect.getMaxY()) );
                 [ +  - ]
     124                 :            :     }
     125         [ +  + ]:       3361 :     if( bIsHorizontalAxis )
     126                 :            :     {
     127         [ +  - ]:       3304 :         return ( (rTickScreenPosition.getX() >= aShapeRect.getMinX())
     128 [ +  - ][ +  - ]:       3304 :             && (rTickScreenPosition.getX() <= aShapeRect.getMaxX()) );
                 [ -  + ]
     129                 :            :     }
     130                 :            : 
     131                 :            :     basegfx::B2IVector aPosition(
     132                 :         57 :         static_cast<sal_Int32>( rTickScreenPosition.getX() )
     133                 :        114 :         , static_cast<sal_Int32>( rTickScreenPosition.getY() ) );
     134         [ +  - ]:       7531 :     return aShapeRect.isInside(aPosition);
     135                 :            : }
     136                 :            : 
     137                 :       7489 : bool doesOverlap( const Reference< drawing::XShape >& xShape1
     138                 :            :                 , const Reference< drawing::XShape >& xShape2
     139                 :            :                 , double fRotationAngleDegree )
     140                 :            : {
     141 [ +  - ][ -  + ]:       7489 :     if( !xShape1.is() || !xShape2.is() )
                 [ -  + ]
     142                 :          0 :         return false;
     143                 :            : 
     144 [ +  - ][ +  - ]:       7489 :     ::basegfx::B2IRectangle aRect1( BaseGFXHelper::makeRectangle(xShape1->getPosition(),ShapeFactory::getSizeAfterRotation( xShape1, fRotationAngleDegree )));
         [ +  - ][ +  - ]
     145 [ +  - ][ +  - ]:       7489 :     ::basegfx::B2IRectangle aRect2( BaseGFXHelper::makeRectangle(xShape2->getPosition(),ShapeFactory::getSizeAfterRotation( xShape2, fRotationAngleDegree )));
         [ +  - ][ +  - ]
     146         [ +  - ]:       7489 :     return aRect1.overlaps(aRect2);
     147                 :            : }
     148                 :            : 
     149                 :         58 : void removeShapesAtWrongRhythm( TickIter& rIter
     150                 :            :                               , sal_Int32 nCorrectRhythm
     151                 :            :                               , sal_Int32 nMaxTickToCheck
     152                 :            :                               , const Reference< drawing::XShapes >& xTarget )
     153                 :            : {
     154                 :         58 :     sal_Int32 nTick = 0;
     155 [ +  + ][ +  + ]:        223 :     for( TickInfo* pTickInfo = rIter.firstInfo()
                 [ +  + ]
     156                 :            :         ; pTickInfo && nTick <= nMaxTickToCheck
     157                 :        165 :         ; pTickInfo = rIter.nextInfo(), nTick++ )
     158                 :            :     {
     159                 :            :         //remove labels which does not fit into the rhythm
     160         [ +  + ]:        165 :         if( nTick%nCorrectRhythm != 0)
     161                 :            :         {
     162         [ +  + ]:         99 :             if(pTickInfo->xTextShape.is())
     163                 :            :             {
     164                 :         24 :                 xTarget->remove(pTickInfo->xTextShape);
     165                 :         24 :                 pTickInfo->xTextShape = NULL;
     166                 :            :             }
     167                 :            :         }
     168                 :            :     }
     169                 :         58 : }
     170                 :            : 
     171 [ +  - ][ -  + ]:       1784 : class LabelIterator : public TickIter
     172                 :            : {
     173                 :            :     //this Iterator iterates over existing text labels
     174                 :            : 
     175                 :            :     //if the labels are staggered and bInnerLine is true
     176                 :            :     //we iterate only through the labels which are lying more inside the diagram
     177                 :            : 
     178                 :            :     //if the labels are staggered and bInnerLine is false
     179                 :            :     //we iterate only through the labels which are lying more outside the diagram
     180                 :            : 
     181                 :            :     //if the labels are not staggered
     182                 :            :     //we iterate through all labels
     183                 :            : 
     184                 :            : public:
     185                 :            :     LabelIterator( ::std::vector< TickInfo >& rTickInfoVector
     186                 :            :             , const AxisLabelStaggering eAxisLabelStaggering
     187                 :            :             , bool bInnerLine );
     188                 :            : 
     189                 :            :     virtual TickInfo*   firstInfo();
     190                 :            :     virtual TickInfo*   nextInfo();
     191                 :            : 
     192                 :            : private: //methods
     193                 :            :     LabelIterator();
     194                 :            : 
     195                 :            : private: //member
     196                 :            :     PureTickIter m_aPureTickIter;
     197                 :            :     const AxisLabelStaggering   m_eAxisLabelStaggering;
     198                 :            :     bool m_bInnerLine;
     199                 :            : };
     200                 :            : 
     201                 :       1784 : LabelIterator::LabelIterator( ::std::vector< TickInfo >& rTickInfoVector
     202                 :            :             , const AxisLabelStaggering eAxisLabelStaggering
     203                 :            :             , bool bInnerLine )
     204                 :            :             : m_aPureTickIter( rTickInfoVector )
     205                 :            :             , m_eAxisLabelStaggering(eAxisLabelStaggering)
     206         [ +  - ]:       1784 :             , m_bInnerLine(bInnerLine)
     207                 :            : {
     208                 :       1784 : }
     209                 :            : 
     210                 :       1781 : TickInfo* LabelIterator::firstInfo()
     211                 :            : {
     212                 :       1781 :     TickInfo* pTickInfo = m_aPureTickIter.firstInfo();
     213 [ +  + ][ +  + ]:       1791 :     while( pTickInfo && !pTickInfo->xTextShape.is() )
                 [ +  + ]
     214                 :         10 :         pTickInfo = m_aPureTickIter.nextInfo();
     215         [ +  + ]:       1781 :     if(!pTickInfo)
     216                 :          2 :         return NULL;
     217 [ +  - ][ +  + ]:       1779 :     if( (STAGGER_EVEN==m_eAxisLabelStaggering && m_bInnerLine)
         [ -  + ][ #  # ]
     218                 :            :         ||
     219                 :          0 :         (STAGGER_ODD==m_eAxisLabelStaggering && !m_bInnerLine)
     220                 :            :         )
     221                 :            :     {
     222                 :            :         //skip first label
     223         [ +  + ]:       1811 :         do
           [ +  +  +  + ]
     224                 :        906 :             pTickInfo = m_aPureTickIter.nextInfo();
     225                 :        905 :         while( pTickInfo && !pTickInfo->xTextShape.is() );
     226                 :            :     }
     227         [ +  + ]:       1779 :     if(!pTickInfo)
     228                 :          1 :         return NULL;
     229                 :       1781 :     return pTickInfo;
     230                 :            : }
     231                 :            : 
     232                 :       3585 : TickInfo* LabelIterator::nextInfo()
     233                 :            : {
     234                 :       3585 :     TickInfo* pTickInfo = NULL;
     235                 :            :     //get next label
     236         [ +  + ]:       7401 :     do
           [ +  +  +  + ]
     237                 :       4145 :         pTickInfo = m_aPureTickIter.nextInfo();
     238                 :       3256 :     while( pTickInfo && !pTickInfo->xTextShape.is() );
     239                 :            : 
     240 [ -  + ][ #  # ]:       3585 :     if(  STAGGER_EVEN==m_eAxisLabelStaggering
     241                 :            :       || STAGGER_ODD==m_eAxisLabelStaggering )
     242                 :            :     {
     243                 :            :         //skip one label
     244         [ +  + ]:       6480 :         do
           [ +  +  +  + ]
     245                 :       4129 :             pTickInfo = m_aPureTickIter.nextInfo();
     246                 :       2351 :         while( pTickInfo && !pTickInfo->xTextShape.is() );
     247                 :            :     }
     248                 :       3585 :     return pTickInfo;
     249                 :            : }
     250                 :            : 
     251                 :        892 : B2DVector lcl_getLabelsDistance( TickIter& rIter, const B2DVector& rDistanceTickToText, double fRotationAngleDegree )
     252                 :            : {
     253                 :            :     //calculates the height or width of a line of labels
     254                 :            :     //thus a following line of labels can be shifted for that distance
     255                 :            : 
     256                 :        892 :     B2DVector aRet(0,0);
     257                 :            : 
     258         [ +  - ]:        892 :     sal_Int32 nDistanceTickToText = static_cast<sal_Int32>( rDistanceTickToText.getLength() );
     259         [ +  - ]:        892 :     if( nDistanceTickToText==0.0)
     260                 :            :         return aRet;
     261                 :            : 
     262                 :        892 :     B2DVector aStaggerDirection(rDistanceTickToText);
     263         [ +  - ]:        892 :     aStaggerDirection.normalize();
     264                 :            : 
     265                 :        892 :     sal_Int32 nDistance=0;
     266         [ +  - ]:        892 :     Reference< drawing::XShape >  xShape2DText(NULL);
     267 [ +  - ][ +  - ]:       2670 :     for( TickInfo* pTickInfo = rIter.firstInfo()
                 [ +  + ]
     268                 :            :         ; pTickInfo
     269                 :       1778 :         ; pTickInfo = rIter.nextInfo() )
     270                 :            :     {
     271         [ +  - ]:       1778 :         xShape2DText = pTickInfo->xTextShape;
     272         [ +  - ]:       1778 :         if( xShape2DText.is() )
     273                 :            :         {
     274         [ +  - ]:       1778 :             awt::Size aSize = ShapeFactory::getSizeAfterRotation( xShape2DText, fRotationAngleDegree );
     275         [ +  + ]:       1778 :             if(fabs(aStaggerDirection.getX())>fabs(aStaggerDirection.getY()))
     276         [ +  - ]:        101 :                 nDistance = ::std::max(nDistance,aSize.Width);
     277                 :            :             else
     278         [ +  - ]:       1778 :                 nDistance = ::std::max(nDistance,aSize.Height);
     279                 :            :         }
     280                 :            :     }
     281                 :            : 
     282         [ +  - ]:        892 :     aRet = aStaggerDirection*nDistance;
     283                 :            : 
     284                 :            :     //add extra distance for vertical distance
     285         [ +  + ]:        892 :     if(fabs(aStaggerDirection.getX())>fabs(aStaggerDirection.getY()))
     286                 :         36 :         aRet += rDistanceTickToText;
     287                 :            : 
     288                 :        892 :     return aRet;
     289                 :            : }
     290                 :            : 
     291                 :        892 : void lcl_shiftLables( TickIter& rIter, const B2DVector& rStaggerDistance )
     292                 :            : {
     293 [ +  - ][ +  + ]:        892 :     if(rStaggerDistance.getLength()==0.0)
     294                 :        892 :         return;
     295         [ +  - ]:        889 :     Reference< drawing::XShape >  xShape2DText(NULL);
     296 [ +  - ][ +  - ]:       2696 :     for( TickInfo* pTickInfo = rIter.firstInfo()
                 [ +  + ]
     297                 :            :         ; pTickInfo
     298                 :       1807 :         ; pTickInfo = rIter.nextInfo() )
     299                 :            :     {
     300         [ +  - ]:       1807 :         xShape2DText = pTickInfo->xTextShape;
     301         [ +  - ]:       1807 :         if( xShape2DText.is() )
     302                 :            :         {
     303 [ +  - ][ +  - ]:       1807 :             awt::Point aPos  = xShape2DText->getPosition();
     304                 :       1807 :             aPos.X += static_cast<sal_Int32>(rStaggerDistance.getX());
     305                 :       1807 :             aPos.Y += static_cast<sal_Int32>(rStaggerDistance.getY());
     306 [ +  - ][ +  - ]:       1807 :             xShape2DText->setPosition( aPos );
     307                 :            :         }
     308                 :        892 :     }
     309                 :            : }
     310                 :            : 
     311                 :          0 : bool lcl_hasWordBreak( const Reference< drawing::XShape >& rxShape )
     312                 :            : {
     313         [ #  # ]:          0 :     if ( rxShape.is() )
     314                 :            :     {
     315                 :          0 :         SvxShape* pShape = SvxShape::getImplementation( rxShape );
     316         [ #  # ]:          0 :         SvxShapeText* pShapeText = dynamic_cast< SvxShapeText* >( pShape );
     317         [ #  # ]:          0 :         if ( pShapeText )
     318                 :            :         {
     319         [ #  # ]:          0 :             SvxTextEditSource* pTextEditSource = dynamic_cast< SvxTextEditSource* >( pShapeText->GetEditSource() );
     320         [ #  # ]:          0 :             if ( pTextEditSource )
     321                 :            :             {
     322                 :          0 :                 pTextEditSource->UpdateOutliner();
     323                 :          0 :                 SvxTextForwarder* pTextForwarder = pTextEditSource->GetTextForwarder();
     324         [ #  # ]:          0 :                 if ( pTextForwarder )
     325                 :            :                 {
     326                 :          0 :                     sal_uInt16 nParaCount = pTextForwarder->GetParagraphCount();
     327         [ #  # ]:          0 :                     for ( sal_uInt16 nPara = 0; nPara < nParaCount; ++nPara )
     328                 :            :                     {
     329                 :          0 :                         sal_uInt16 nLineCount = pTextForwarder->GetLineCount( nPara );
     330         [ #  # ]:          0 :                         for ( sal_uInt16 nLine = 0; nLine < nLineCount; ++nLine )
     331                 :            :                         {
     332                 :          0 :                             sal_uInt16 nLineStart = 0;
     333                 :          0 :                             sal_uInt16 nLineEnd = 0;
     334         [ #  # ]:          0 :                             pTextForwarder->GetLineBoundaries( nLineStart, nLineEnd, nPara, nLine );
     335                 :          0 :                             sal_uInt16 nWordStart = 0;
     336                 :          0 :                             sal_uInt16 nWordEnd = 0;
     337 [ #  # ][ #  # ]:          0 :                             if ( pTextForwarder->GetWordIndices( nPara, nLineStart, nWordStart, nWordEnd ) &&
         [ #  # ][ #  # ]
     338                 :            :                                  ( nWordStart != nLineStart ) )
     339                 :            :                             {
     340                 :          0 :                                 return true;
     341                 :            :                             }
     342                 :            :                         }
     343                 :            :                     }
     344                 :            :                 }
     345                 :            :             }
     346                 :            :         }
     347                 :            :     }
     348                 :            : 
     349                 :          0 :     return false;
     350                 :            : }
     351                 :            : 
     352                 :            : class MaxLabelTickIter : public TickIter
     353                 :            : {
     354                 :            :     //iterate over first two and last two labels and the longest label
     355                 :            : public:
     356                 :            :     MaxLabelTickIter( ::std::vector< TickInfo >& rTickInfoVector
     357                 :            :             , sal_Int32 nLongestLabelIndex );
     358                 :            :     virtual ~MaxLabelTickIter();
     359                 :            : 
     360                 :            :     virtual TickInfo* firstInfo();
     361                 :            :     virtual TickInfo* nextInfo();
     362                 :            : 
     363                 :            : private:
     364                 :            :     ::std::vector< TickInfo >& m_rTickInfoVector;
     365                 :            :     ::std::vector< sal_Int32 > m_aValidIndices;
     366                 :            :     sal_Int32 m_nCurrentIndex;
     367                 :            : };
     368                 :            : 
     369                 :       1681 : MaxLabelTickIter::MaxLabelTickIter( ::std::vector< TickInfo >& rTickInfoVector
     370                 :            :             , sal_Int32 nLongestLabelIndex )
     371                 :            :             : m_rTickInfoVector(rTickInfoVector)
     372         [ +  - ]:       1681 :             , m_nCurrentIndex(0)
     373                 :            : {
     374                 :       1681 :     sal_Int32 nMaxIndex = m_rTickInfoVector.size()-1;
     375 [ +  + ][ +  - ]:       1681 :     if( nLongestLabelIndex<0 || nLongestLabelIndex>=nMaxIndex-1 )
     376                 :         16 :         nLongestLabelIndex = 0;
     377                 :            : 
     378         [ +  - ]:       1681 :     if( nMaxIndex>=0 )
     379         [ +  - ]:       1681 :         m_aValidIndices.push_back(0);
     380         [ +  + ]:       1681 :     if( nMaxIndex>=1 )
     381         [ +  - ]:       1680 :         m_aValidIndices.push_back(1);
     382         [ -  + ]:       1681 :     if( nLongestLabelIndex>1 )
     383         [ #  # ]:          0 :         m_aValidIndices.push_back(nLongestLabelIndex);
     384         [ +  + ]:       1681 :     if( nMaxIndex > 2 )
     385         [ +  - ]:       1631 :         m_aValidIndices.push_back(nMaxIndex-1);
     386         [ +  + ]:       1681 :     if( nMaxIndex > 1 )
     387         [ +  - ]:       1668 :         m_aValidIndices.push_back(nMaxIndex);
     388                 :       1681 : }
     389                 :       1681 : MaxLabelTickIter::~MaxLabelTickIter()
     390                 :            : {
     391         [ -  + ]:       3362 : }
     392                 :            : 
     393                 :       1681 : TickInfo* MaxLabelTickIter::firstInfo()
     394                 :            : {
     395                 :       1681 :     m_nCurrentIndex = 0;
     396         [ +  - ]:       1681 :     if( m_nCurrentIndex < static_cast<sal_Int32>(m_aValidIndices.size()) )
     397                 :       1681 :         return &m_rTickInfoVector[m_aValidIndices[m_nCurrentIndex]];
     398                 :       1681 :     return 0;
     399                 :            : }
     400                 :            : 
     401                 :       6660 : TickInfo* MaxLabelTickIter::nextInfo()
     402                 :            : {
     403                 :       6660 :     m_nCurrentIndex++;
     404 [ +  - ][ +  + ]:       6660 :     if( m_nCurrentIndex>=0 && m_nCurrentIndex<static_cast<sal_Int32>(m_aValidIndices.size()) )
                 [ +  + ]
     405                 :       4979 :         return &m_rTickInfoVector[m_aValidIndices[m_nCurrentIndex]];
     406                 :       6660 :     return 0;
     407                 :            : }
     408                 :            : 
     409                 :       3420 : bool VCartesianAxis::isBreakOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties
     410                 :            :                                                      , bool bIsHorizontalAxis )
     411                 :            : {
     412         [ -  + ]:       3420 :     if( m_aTextLabels.getLength() > 100 )
     413                 :          0 :         return false;
     414         [ +  + ]:       3420 :     if( !rAxisLabelProperties.bLineBreakAllowed )
     415                 :       3303 :         return false;
     416         [ -  + ]:        117 :     if( rAxisLabelProperties.bStackCharacters )
     417                 :          0 :         return false;
     418                 :            :     //no break for value axis
     419         [ +  + ]:        117 :     if( !m_bUseTextLabels )
     420                 :         14 :         return false;
     421         [ +  + ]:        103 :     if( !::rtl::math::approxEqual( rAxisLabelProperties.fRotationAngleDegree, 0.0 ) )
     422                 :          3 :         return false;
     423                 :            :     //break only for horizontal axis
     424                 :       3420 :     return bIsHorizontalAxis;
     425                 :            : }
     426                 :            : 
     427                 :       1731 : bool VCartesianAxis::isAutoStaggeringOfLabelsAllowed( const AxisLabelProperties& rAxisLabelProperties
     428                 :            :                                                      , bool bIsHorizontalAxis, bool bIsVerticalAxis )
     429                 :            : {
     430         [ +  + ]:       1731 :     if( rAxisLabelProperties.eStaggering != STAGGER_AUTO )
     431                 :        215 :         return false;
     432         [ +  + ]:       1516 :     if( rAxisLabelProperties.bOverlapAllowed )
     433                 :          8 :         return false;
     434         [ -  + ]:       1508 :     if( rAxisLabelProperties.bLineBreakAllowed ) //auto line break or auto staggering, doing both automatisms they may conflict...
     435                 :          0 :         return false;
     436         [ -  + ]:       1508 :     if( !::rtl::math::approxEqual( rAxisLabelProperties.fRotationAngleDegree, 0.0 ) )
     437                 :          0 :         return false;
     438                 :            :     //automatic staggering only for horizontal axis with horizontal text
     439                 :            :     //or vertical axis with vertical text
     440         [ +  + ]:       1508 :     if( bIsHorizontalAxis )
     441                 :        856 :         return !rAxisLabelProperties.bStackCharacters;
     442         [ +  + ]:        652 :     if( bIsVerticalAxis )
     443                 :        637 :         return rAxisLabelProperties.bStackCharacters;
     444                 :       1731 :     return false;
     445                 :            : }
     446                 :            : 
     447                 :            : struct ComplexCategoryPlacement
     448                 :            : {
     449                 :            :     rtl::OUString Text;
     450                 :            :     sal_Int32 Count;
     451                 :            :     double TickValue;
     452                 :            : 
     453                 :            :     ComplexCategoryPlacement( const rtl::OUString& rText, sal_Int32 nCount, double fTickValue )
     454                 :            :         : Text(rText), Count(nCount), TickValue(fTickValue)
     455                 :            :     {}
     456                 :            : };
     457                 :            : 
     458                 :          0 : void VCartesianAxis::createAllTickInfosFromComplexCategories( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos, bool bShiftedPosition )
     459                 :            : {
     460                 :            :     //no minor tickmarks will be generated!
     461                 :            :     //order is: inner labels first , outer labels last (that is different to all other TickIter cases)
     462         [ #  # ]:          0 :     if(!bShiftedPosition)
     463                 :            :     {
     464                 :          0 :         rAllTickInfos.clear();
     465                 :          0 :         sal_Int32 nLevel=0;
     466                 :          0 :         sal_Int32 nLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
     467                 :          0 :         sal_Int32 nCatIndex = 0;
     468         [ #  # ]:          0 :         for( ; nLevel<nLevelCount; nLevel++ )
     469                 :            :         {
     470         [ #  # ]:          0 :             ::std::vector< TickInfo > aTickInfoVector;
     471         [ #  # ]:          0 :             std::vector< ComplexCategory > aComplexCategories( m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoriesByLevel( nLevel ) );
     472         [ #  # ]:          0 :             std::vector< ComplexCategory >::const_iterator aIt(aComplexCategories.begin());
     473         [ #  # ]:          0 :             std::vector< ComplexCategory >::const_iterator aEnd(aComplexCategories.end());
     474 [ #  # ][ #  # ]:          0 :             for(;aIt!=aEnd;++aIt)
                 [ #  # ]
     475                 :            :             {
     476 [ #  # ][ #  # ]:          0 :                 TickInfo aTickInfo(0);
     477 [ #  # ][ #  # ]:          0 :                 ComplexCategory aCat(*aIt);
     478                 :          0 :                 sal_Int32 nCount = aCat.Count;
     479         [ #  # ]:          0 :                 if( nCatIndex + 1.0 + nCount >= m_aScale.Maximum )
     480                 :            :                 {
     481                 :          0 :                     nCount = static_cast<sal_Int32>(m_aScale.Maximum - 1.0 - nCatIndex);
     482         [ #  # ]:          0 :                     if( nCount <= 0 )
     483                 :          0 :                         nCount = 1;
     484                 :            :                 }
     485                 :          0 :                 aTickInfo.fScaledTickValue = nCatIndex + 1.0 + nCount/2.0;
     486                 :          0 :                 aTickInfo.nFactorForLimitedTextWidth = nCount;
     487                 :          0 :                 aTickInfo.aText = aCat.Text;
     488         [ #  # ]:          0 :                 aTickInfoVector.push_back(aTickInfo);
     489                 :          0 :                 nCatIndex += nCount;
     490         [ #  # ]:          0 :                 if( nCatIndex + 1.0 >= m_aScale.Maximum )
     491                 :            :                     break;
     492 [ #  # ][ #  # ]:          0 :             }
         [ #  # ][ #  # ]
     493         [ #  # ]:          0 :             rAllTickInfos.push_back(aTickInfoVector);
     494                 :          0 :         }
     495                 :            :     }
     496                 :            :     else //bShiftedPosition==false
     497                 :            :     {
     498                 :          0 :         rAllTickInfos.clear();
     499                 :          0 :         sal_Int32 nLevel=0;
     500                 :          0 :         sal_Int32 nLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
     501         [ #  # ]:          0 :         for( ; nLevel<nLevelCount; nLevel++ )
     502                 :            :         {
     503         [ #  # ]:          0 :             ::std::vector< TickInfo > aTickInfoVector;
     504         [ #  # ]:          0 :             std::vector< ComplexCategory > aComplexCategories( m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoriesByLevel( nLevel ) );
     505                 :          0 :             sal_Int32 nCatIndex = 0;
     506         [ #  # ]:          0 :             std::vector< ComplexCategory >::const_iterator aIt(aComplexCategories.begin());
     507         [ #  # ]:          0 :             std::vector< ComplexCategory >::const_iterator aEnd(aComplexCategories.end());
     508 [ #  # ][ #  # ]:          0 :             for(;aIt!=aEnd;++aIt)
                 [ #  # ]
     509                 :            :             {
     510 [ #  # ][ #  # ]:          0 :                 TickInfo aTickInfo(0);
     511 [ #  # ][ #  # ]:          0 :                 ComplexCategory aCat(*aIt);
     512                 :          0 :                 aTickInfo.fScaledTickValue = nCatIndex + 1.0;
     513         [ #  # ]:          0 :                 aTickInfoVector.push_back(aTickInfo);
     514                 :          0 :                 nCatIndex += aCat.Count;
     515         [ #  # ]:          0 :                 if( nCatIndex + 1.0 > m_aScale.Maximum )
     516                 :            :                     break;
     517 [ #  # ][ #  # ]:          0 :             }
         [ #  # ][ #  # ]
     518                 :            :             //fill up with single ticks until maximum scale
     519         [ #  # ]:          0 :             while( nCatIndex + 1.0 < m_aScale.Maximum )
     520                 :            :             {
     521 [ #  # ][ #  # ]:          0 :                 TickInfo aTickInfo(0);
     522                 :          0 :                 aTickInfo.fScaledTickValue = nCatIndex + 1.0;
     523         [ #  # ]:          0 :                 aTickInfoVector.push_back(aTickInfo);
     524                 :          0 :                 nCatIndex ++;
     525         [ #  # ]:          0 :                 if( nLevel>0 )
     526                 :            :                     break;
     527 [ #  # ][ #  # ]:          0 :             }
     528                 :            :             //add an additional tick at the end
     529                 :            :             {
     530 [ #  # ][ #  # ]:          0 :                 TickInfo aTickInfo(0);
     531                 :          0 :                 aTickInfo.fScaledTickValue = m_aScale.Maximum;
     532 [ #  # ][ #  # ]:          0 :                 aTickInfoVector.push_back(aTickInfo);
     533                 :            :             }
     534         [ #  # ]:          0 :             rAllTickInfos.push_back(aTickInfoVector);
     535                 :          0 :         }
     536                 :            :     }
     537                 :          0 : }
     538                 :            : 
     539                 :       3640 : void VCartesianAxis::createAllTickInfos( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos )
     540                 :            : {
     541         [ -  + ]:       3640 :     if( isComplexCategoryAxis() )
     542                 :          0 :         createAllTickInfosFromComplexCategories( rAllTickInfos, false );
     543                 :            :     else
     544                 :       3640 :         VAxisBase::createAllTickInfos(rAllTickInfos);
     545                 :       3640 : }
     546                 :            : 
     547                 :       1681 : TickIter* VCartesianAxis::createLabelTickIterator( sal_Int32 nTextLevel )
     548                 :            : {
     549 [ +  - ][ +  - ]:       1681 :     if( nTextLevel>=0 && nTextLevel < static_cast< sal_Int32 >(m_aAllTickInfos.size()) )
                 [ +  - ]
     550         [ +  - ]:       1681 :         return new PureTickIter( m_aAllTickInfos[nTextLevel] );
     551                 :       1681 :     return NULL;
     552                 :            : }
     553                 :            : 
     554                 :       1681 : TickIter* VCartesianAxis::createMaximumLabelTickIterator( sal_Int32 nTextLevel )
     555                 :            : {
     556 [ +  - ][ -  + ]:       1681 :     if( isComplexCategoryAxis() || isDateAxis() )
                 [ -  + ]
     557                 :            :     {
     558                 :          0 :         return createLabelTickIterator( nTextLevel ); //mmmm maybe todo: create less than all texts here
     559                 :            :     }
     560                 :            :     else
     561                 :            :     {
     562         [ +  - ]:       1681 :         if(nTextLevel==0)
     563                 :            :         {
     564         [ +  - ]:       1681 :             if( !m_aAllTickInfos.empty() )
     565                 :            :             {
     566         [ +  + ]:       1681 :                 sal_Int32 nLongestLabelIndex = m_bUseTextLabels ? this->getIndexOfLongestLabel( m_aTextLabels ) : 0;
     567         [ +  - ]:       1681 :                 return new MaxLabelTickIter( m_aAllTickInfos[0], nLongestLabelIndex );
     568                 :            :             }
     569                 :            :         }
     570                 :            :     }
     571                 :       1681 :     return NULL;
     572                 :            : }
     573                 :            : 
     574                 :       3362 : sal_Int32 VCartesianAxis::getTextLevelCount() const
     575                 :            : {
     576                 :       3362 :     sal_Int32 nTextLevelCount = 1;
     577         [ -  + ]:       3362 :     if( isComplexCategoryAxis() )
     578                 :          0 :         nTextLevelCount = m_aAxisProperties.m_pExplicitCategoriesProvider->getCategoryLevelCount();
     579                 :       3362 :     return nTextLevelCount;
     580                 :            : }
     581                 :            : 
     582                 :       3420 : bool VCartesianAxis::createTextShapes(
     583                 :            :                        const Reference< drawing::XShapes >& xTarget
     584                 :            :                      , TickIter& rTickIter
     585                 :            :                      , AxisLabelProperties& rAxisLabelProperties
     586                 :            :                      , TickFactory_2D* pTickFactory
     587                 :            :                      , sal_Int32 nScreenDistanceBetweenTicks )
     588                 :            : {
     589                 :            :     //returns true if the text shapes have been created successfully
     590                 :            :     //otherwise false - in this case the AxisLabelProperties have changed
     591                 :            :     //and contain new instructions for the next try for text shape creation
     592                 :            : 
     593         [ +  - ]:       3420 :     Reference< XScaling > xInverseScaling( NULL );
     594         [ +  + ]:       3420 :     if( m_aScale.Scaling.is() )
     595 [ +  - ][ +  - ]:       1452 :         xInverseScaling = m_aScale.Scaling->getInverseScaling();
                 [ +  - ]
     596                 :            : 
     597                 :            :     FixedNumberFormatter aFixedNumberFormatter(
     598         [ +  - ]:       3420 :                 m_xNumberFormatsSupplier, rAxisLabelProperties.nNumberFormatKey );
     599                 :            : 
     600         [ +  - ]:       3420 :     const bool bIsHorizontalAxis = pTickFactory->isHorizontalAxis();
     601         [ +  - ]:       3420 :     const bool bIsVerticalAxis = pTickFactory->isVerticalAxis();
     602         [ +  - ]:       3420 :     bool bIsStaggered = rAxisLabelProperties.getIsStaggered();
     603         [ +  - ]:       3420 :     B2DVector aTextToTickDistance( pTickFactory->getDistanceAxisTickToText( m_aAxisProperties, true ) );
     604                 :       3420 :     sal_Int32 nLimitedSpaceForText = -1;
     605 [ +  - ][ +  + ]:       3420 :     if( isBreakOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis ) )
     606                 :            :     {
     607                 :        100 :         nLimitedSpaceForText = nScreenDistanceBetweenTicks;
     608         [ -  + ]:        100 :         if( bIsStaggered )
     609                 :          0 :             nLimitedSpaceForText *= 2;
     610                 :            : 
     611         [ +  - ]:        100 :         if( nLimitedSpaceForText > 0 )
     612                 :            :         { //reduce space for a small amount to have a visible distance between the labels:
     613                 :        100 :             sal_Int32 nReduce = (nLimitedSpaceForText*5)/100;
     614         [ -  + ]:        100 :             if(!nReduce)
     615                 :          0 :                 nReduce = 1;
     616                 :        100 :             nLimitedSpaceForText -= nReduce;
     617                 :            :         }
     618                 :            :     }
     619                 :            : 
     620                 :       3420 :     uno::Sequence< rtl::OUString >* pCategories = 0;
     621 [ +  + ][ +  - ]:       3420 :     if( m_bUseTextLabels && !m_aAxisProperties.m_bComplexCategories )
     622                 :       1942 :         pCategories = &m_aTextLabels;
     623                 :            : 
     624                 :       3420 :     TickInfo* pPreviousVisibleTickInfo = NULL;
     625                 :       3420 :     TickInfo* pPREPreviousVisibleTickInfo = NULL;
     626                 :       3420 :     TickInfo* pLastVisibleNeighbourTickInfo = NULL;
     627                 :            : 
     628                 :            :     //------------------------------------------------
     629                 :            :     //prepare properties for multipropertyset-interface of shape
     630         [ +  - ]:       3420 :     tNameSequence aPropNames;
     631         [ +  - ]:       3420 :     tAnySequence aPropValues;
     632                 :            : 
     633                 :       3420 :     bool bLimitedHeight = fabs(aTextToTickDistance.getX()) > fabs(aTextToTickDistance.getY());
     634         [ +  - ]:       3420 :     Reference< beans::XPropertySet > xProps( m_aAxisProperties.m_xAxisModel, uno::UNO_QUERY );
     635                 :            :     PropertyMapper::getTextLabelMultiPropertyLists( xProps, aPropNames, aPropValues, false
     636         [ +  - ]:       3420 :         , nLimitedSpaceForText, bLimitedHeight );
     637                 :            :     LabelPositionHelper::doDynamicFontResize( aPropValues, aPropNames, xProps
     638         [ +  - ]:       3420 :         , m_aAxisLabelProperties.m_aFontReferenceSize );
     639         [ +  - ]:       3420 :     LabelPositionHelper::changeTextAdjustment( aPropValues, aPropNames, m_aAxisProperties.m_aLabelAlignment );
     640                 :            : 
     641 [ +  - ][ +  - ]:       3420 :     uno::Any* pColorAny = PropertyMapper::getValuePointer(aPropValues,aPropNames,C2U("CharColor"));
     642                 :       3420 :     sal_Int32 nColor = Color( COL_AUTO ).GetColor();
     643         [ +  - ]:       3420 :     if(pColorAny)
     644                 :       3420 :         *pColorAny >>= nColor;
     645                 :            : 
     646         [ +  - ]:       3420 :     uno::Any* pLimitedSpaceAny = PropertyMapper::getValuePointerForLimitedSpace(aPropValues,aPropNames,bLimitedHeight);
     647                 :            :     //------------------------------------------------
     648                 :            : 
     649                 :       3420 :     sal_Int32 nTick = 0;
     650 [ +  - ][ +  - ]:      19520 :     for( TickInfo* pTickInfo = rTickIter.firstInfo()
                 [ +  + ]
     651                 :            :         ; pTickInfo
     652                 :      16100 :         ; pTickInfo = rTickIter.nextInfo(), nTick++ )
     653                 :            :     {
     654                 :            :         pLastVisibleNeighbourTickInfo = bIsStaggered ?
     655         [ +  + ]:      16158 :                     pPREPreviousVisibleTickInfo : pPreviousVisibleTickInfo;
     656                 :            : 
     657                 :            :         //don't create labels which does not fit into the rhythm
     658         [ +  + ]:      16158 :         if( nTick%rAxisLabelProperties.nRhythm != 0)
     659                 :        107 :             continue;
     660                 :            : 
     661                 :            :         //don't create labels for invisible ticks
     662         [ -  + ]:      16051 :         if( !pTickInfo->bPaintIt )
     663                 :          0 :             continue;
     664                 :            : 
     665                 :            :         //if NO OVERLAP -> don't create labels where the tick overlaps
     666                 :            :         //with the text of the last neighbour tickmark
     667 [ +  + ][ +  + ]:      16051 :         if( pLastVisibleNeighbourTickInfo && !rAxisLabelProperties.bOverlapAllowed )
     668                 :            :         {
     669 [ +  - ][ +  + ]:       7531 :             if( lcl_doesShapeOverlapWithTickmark( pLastVisibleNeighbourTickInfo->xTextShape
     670                 :            :                        , rAxisLabelProperties.fRotationAngleDegree
     671                 :            :                        , pTickInfo->aTickScreenPosition
     672                 :       7531 :                        , bIsHorizontalAxis, bIsVerticalAxis ) )
     673                 :            :             {
     674                 :         42 :                 bool bOverlapAlsoAfterSwitchingOnAutoStaggering = true;
     675 [ +  + ][ -  + ]:         42 :                 if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis ) )
                 [ -  + ]
     676                 :            :                 {
     677                 :          0 :                     bIsStaggered = true;
     678                 :          0 :                     rAxisLabelProperties.eStaggering = STAGGER_EVEN;
     679                 :          0 :                     pLastVisibleNeighbourTickInfo = pPREPreviousVisibleTickInfo;
     680 [ #  # ][ #  # ]:          0 :                     if( !pLastVisibleNeighbourTickInfo ||
                 [ #  # ]
     681                 :            :                         !lcl_doesShapeOverlapWithTickmark( pLastVisibleNeighbourTickInfo->xTextShape
     682                 :            :                                 , rAxisLabelProperties.fRotationAngleDegree
     683                 :            :                                 , pTickInfo->aTickScreenPosition
     684         [ #  # ]:          0 :                                 , bIsHorizontalAxis, bIsVerticalAxis ) )
     685                 :          0 :                         bOverlapAlsoAfterSwitchingOnAutoStaggering = false;
     686                 :            :                 }
     687         [ +  - ]:         42 :                 if( bOverlapAlsoAfterSwitchingOnAutoStaggering )
     688                 :            :                 {
     689         [ -  + ]:         42 :                     if( rAxisLabelProperties.bRhythmIsFix )
     690                 :          0 :                         continue;
     691                 :         42 :                     rAxisLabelProperties.nRhythm++;
     692         [ +  - ]:         42 :                     removeShapesAtWrongRhythm( rTickIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
     693                 :         42 :                     return false;
     694                 :            :                 }
     695                 :            :             }
     696                 :            :         }
     697                 :            : 
     698                 :            :         //xxxxx pTickInfo->updateUnscaledValue( xInverseScaling );
     699                 :            : 
     700                 :      16009 :         bool bHasExtraColor=false;
     701                 :      16009 :         sal_Int32 nExtraColor=0;
     702                 :            : 
     703                 :      16009 :         rtl::OUString aLabel;
     704         [ +  + ]:      16009 :         if(pCategories)
     705                 :            :         {
     706         [ +  - ]:       8195 :             sal_Int32 nIndex = static_cast< sal_Int32 >(pTickInfo->getUnscaledTickValue()) - 1; //first category (index 0) matches with real number 1.0
     707 [ +  - ][ +  + ]:       8195 :             if( nIndex>=0 && nIndex<pCategories->getLength() )
                 [ +  + ]
     708         [ +  - ]:       8183 :                 aLabel = (*pCategories)[nIndex];
     709                 :            :         }
     710         [ -  + ]:       7814 :         else if( m_aAxisProperties.m_bComplexCategories )
     711                 :            :         {
     712                 :          0 :             aLabel = pTickInfo->aText;
     713                 :            :         }
     714                 :            :         else
     715 [ +  - ][ +  - ]:       7814 :             aLabel = aFixedNumberFormatter.getFormattedString( pTickInfo->getUnscaledTickValue(), nExtraColor, bHasExtraColor );
     716                 :            : 
     717         [ +  - ]:      16009 :         if(pColorAny)
     718 [ -  + ][ +  - ]:      16009 :             *pColorAny = uno::makeAny(bHasExtraColor?nExtraColor:nColor);
     719         [ +  + ]:      16009 :         if(pLimitedSpaceAny)
     720         [ +  - ]:        400 :             *pLimitedSpaceAny = uno::makeAny(sal_Int32(nLimitedSpaceForText*pTickInfo->nFactorForLimitedTextWidth));
     721                 :            : 
     722                 :      16009 :         B2DVector aTickScreenPos2D( pTickInfo->aTickScreenPosition );
     723                 :      16009 :         aTickScreenPos2D += aTextToTickDistance;
     724                 :            :         awt::Point aAnchorScreenPosition2D(
     725                 :      16009 :             static_cast<sal_Int32>(aTickScreenPos2D.getX())
     726                 :      32018 :             ,static_cast<sal_Int32>(aTickScreenPos2D.getY()));
     727                 :            : 
     728                 :            :         //create single label
     729         [ +  + ]:      16009 :         if(!pTickInfo->xTextShape.is())
     730                 :            :             pTickInfo->xTextShape = createSingleLabel( m_xShapeFactory, xTarget
     731                 :            :                                     , aAnchorScreenPosition2D, aLabel
     732                 :            :                                     , rAxisLabelProperties, m_aAxisProperties
     733 [ +  - ][ +  - ]:      15951 :                                     , aPropNames, aPropValues );
     734         [ +  + ]:      16009 :         if(!pTickInfo->xTextShape.is())
     735                 :         18 :             continue;
     736                 :            : 
     737         [ +  - ]:      15991 :         recordMaximumTextSize( pTickInfo->xTextShape, rAxisLabelProperties.fRotationAngleDegree );
     738                 :            : 
     739                 :            :          //better rotate if single words are broken apart
     740         [ +  + ]:      16391 :         if( nLimitedSpaceForText>0 && !rAxisLabelProperties.bOverlapAllowed
           [ +  -  +  - ]
         [ -  + ][ #  # ]
                 [ -  + ]
     741                 :        400 :                 && ::rtl::math::approxEqual( rAxisLabelProperties.fRotationAngleDegree, 0.0 )
     742                 :            :                 && m_aAxisProperties.m_bComplexCategories
     743         [ #  # ]:          0 :                 && lcl_hasWordBreak( pTickInfo->xTextShape ) )
     744                 :            :         {
     745                 :          0 :             rAxisLabelProperties.fRotationAngleDegree = 90;
     746                 :          0 :             rAxisLabelProperties.bLineBreakAllowed = false;
     747                 :          0 :             m_aAxisLabelProperties.fRotationAngleDegree = rAxisLabelProperties.fRotationAngleDegree;
     748         [ #  # ]:          0 :             removeTextShapesFromTicks();
     749                 :          0 :             return false;
     750                 :            :         }
     751                 :            : 
     752                 :            :         //if NO OVERLAP -> remove overlapping shapes
     753 [ +  + ][ +  + ]:      15991 :         if( pLastVisibleNeighbourTickInfo && !rAxisLabelProperties.bOverlapAllowed )
     754                 :            :         {
     755 [ +  - ][ +  + ]:       7489 :             if( doesOverlap( pLastVisibleNeighbourTickInfo->xTextShape, pTickInfo->xTextShape, rAxisLabelProperties.fRotationAngleDegree ) )
     756                 :            :             {
     757                 :         16 :                 bool bOverlapAlsoAfterSwitchingOnAutoStaggering = true;
     758 [ +  - ][ -  + ]:         16 :                 if( !bIsStaggered && isAutoStaggeringOfLabelsAllowed( rAxisLabelProperties, bIsHorizontalAxis, bIsVerticalAxis ) )
                 [ -  + ]
     759                 :            :                 {
     760                 :          0 :                     bIsStaggered = true;
     761                 :          0 :                     rAxisLabelProperties.eStaggering = STAGGER_EVEN;
     762                 :          0 :                     pLastVisibleNeighbourTickInfo = pPREPreviousVisibleTickInfo;
     763 [ #  # ][ #  # ]:          0 :                     if( !pLastVisibleNeighbourTickInfo ||
                 [ #  # ]
     764                 :            :                         !lcl_doesShapeOverlapWithTickmark( pLastVisibleNeighbourTickInfo->xTextShape
     765                 :            :                             , rAxisLabelProperties.fRotationAngleDegree
     766                 :            :                             , pTickInfo->aTickScreenPosition
     767         [ #  # ]:          0 :                             , bIsHorizontalAxis, bIsVerticalAxis ) )
     768                 :          0 :                         bOverlapAlsoAfterSwitchingOnAutoStaggering = false;
     769                 :            :                 }
     770         [ +  - ]:         16 :                 if( bOverlapAlsoAfterSwitchingOnAutoStaggering )
     771                 :            :                 {
     772         [ -  + ]:         16 :                     if( rAxisLabelProperties.bRhythmIsFix )
     773                 :            :                     {
     774 [ #  # ][ #  # ]:          0 :                         xTarget->remove(pTickInfo->xTextShape);
     775         [ #  # ]:          0 :                         pTickInfo->xTextShape = NULL;
     776                 :          0 :                         continue;
     777                 :            :                     }
     778                 :         16 :                     rAxisLabelProperties.nRhythm++;
     779         [ +  - ]:         16 :                     removeShapesAtWrongRhythm( rTickIter, rAxisLabelProperties.nRhythm, nTick, xTarget );
     780                 :         16 :                     return false;
     781                 :            :                 }
     782                 :            :             }
     783                 :            :         }
     784                 :            : 
     785                 :      15975 :         pPREPreviousVisibleTickInfo = pPreviousVisibleTickInfo;
     786      [ +  +  + ]:      31984 :         pPreviousVisibleTickInfo = pTickInfo;
     787      [ +  +  + ]:      32167 :     }
     788 [ +  - ][ +  - ]:       3420 :     return true;
                 [ +  - ]
     789                 :            : }
     790                 :            : 
     791                 :          0 : drawing::PointSequenceSequence lcl_makePointSequence( B2DVector& rStart, B2DVector& rEnd )
     792                 :            : {
     793                 :          0 :     drawing::PointSequenceSequence aPoints(1);
     794 [ #  # ][ #  # ]:          0 :     aPoints[0].realloc(2);
     795 [ #  # ][ #  # ]:          0 :     aPoints[0][0].X = static_cast<sal_Int32>(rStart.getX());
     796 [ #  # ][ #  # ]:          0 :     aPoints[0][0].Y = static_cast<sal_Int32>(rStart.getY());
     797 [ #  # ][ #  # ]:          0 :     aPoints[0][1].X = static_cast<sal_Int32>(rEnd.getX());
     798 [ #  # ][ #  # ]:          0 :     aPoints[0][1].Y = static_cast<sal_Int32>(rEnd.getY());
     799                 :          0 :     return aPoints;
     800                 :            : }
     801                 :            : 
     802                 :      22282 : double VCartesianAxis::getLogicValueWhereMainLineCrossesOtherAxis() const
     803                 :            : {
     804         [ +  + ]:      22282 :     double fMin = (m_nDimensionIndex==1) ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMinY();
     805         [ +  + ]:      22282 :     double fMax = (m_nDimensionIndex==1) ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMaxY();
     806                 :            : 
     807                 :            :     double fCrossesOtherAxis;
     808         [ +  + ]:      22282 :     if(m_aAxisProperties.m_pfMainLinePositionAtOtherAxis)
     809                 :      20706 :         fCrossesOtherAxis = *m_aAxisProperties.m_pfMainLinePositionAtOtherAxis;
     810                 :            :     else
     811                 :            :     {
     812         [ -  + ]:       1576 :         if( ::com::sun::star::chart::ChartAxisPosition_END == m_aAxisProperties.m_eCrossoverType )
     813                 :          0 :             fCrossesOtherAxis = fMax;
     814                 :            :         else
     815                 :       1576 :             fCrossesOtherAxis = fMin;
     816                 :            :     }
     817                 :      22282 :     return fCrossesOtherAxis;
     818                 :            : }
     819                 :            : 
     820                 :      10598 : double VCartesianAxis::getLogicValueWhereLabelLineCrossesOtherAxis() const
     821                 :            : {
     822         [ +  + ]:      10598 :     double fMin = (m_nDimensionIndex==1) ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMinY();
     823         [ +  + ]:      10598 :     double fMax = (m_nDimensionIndex==1) ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMaxY();
     824                 :            : 
     825                 :            :     double fCrossesOtherAxis;
     826         [ +  + ]:      10598 :     if( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START == m_aAxisProperties.m_eLabelPos )
     827                 :        600 :         fCrossesOtherAxis = fMin;
     828         [ -  + ]:       9998 :     else if( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END == m_aAxisProperties.m_eLabelPos )
     829                 :          0 :         fCrossesOtherAxis = fMax;
     830                 :            :     else
     831                 :       9998 :         fCrossesOtherAxis = getLogicValueWhereMainLineCrossesOtherAxis();
     832                 :      10598 :     return fCrossesOtherAxis;
     833                 :            : }
     834                 :            : 
     835                 :          0 : bool VCartesianAxis::getLogicValueWhereExtraLineCrossesOtherAxis( double& fCrossesOtherAxis ) const
     836                 :            : {
     837         [ #  # ]:          0 :     if( !m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis )
     838                 :          0 :         return false;
     839         [ #  # ]:          0 :     double fMin = (m_nDimensionIndex==1) ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMinY();
     840         [ #  # ]:          0 :     double fMax = (m_nDimensionIndex==1) ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMaxY();
     841 [ #  # ][ #  # ]:          0 :     if( *m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis <= fMin
     842                 :            :         || *m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis >= fMax )
     843                 :          0 :         return false;
     844                 :          0 :     fCrossesOtherAxis = *m_aAxisProperties.m_pfExrtaLinePositionAtOtherAxis;
     845                 :          0 :     return true;
     846                 :            : }
     847                 :            : 
     848                 :      45764 : B2DVector VCartesianAxis::getScreenPosition( double fLogicX, double fLogicY, double fLogicZ ) const
     849                 :            : {
     850                 :      45764 :     B2DVector aRet(0,0);
     851                 :            : 
     852         [ +  - ]:      45764 :     if( m_pPosHelper )
     853                 :            :     {
     854         [ +  - ]:      45764 :         drawing::Position3D aScenePos = m_pPosHelper->transformLogicToScene( fLogicX, fLogicY, fLogicZ, true );
     855         [ +  + ]:      45764 :         if(3==m_nDimension)
     856                 :            :         {
     857 [ +  - ][ +  - ]:       1036 :             if( m_xLogicTarget.is() && m_pPosHelper && m_pShapeFactory )
         [ +  - ][ +  - ]
     858                 :            :             {
     859         [ +  - ]:       1036 :                 tPropertyNameMap aDummyPropertyNameMap;
     860                 :            :                 Reference< drawing::XShape > xShape3DAnchor = m_pShapeFactory->createCube( m_xLogicTarget
     861 [ +  - ][ +  - ]:       1036 :                         , aScenePos,drawing::Direction3D(1,1,1), 0, 0, aDummyPropertyNameMap);
     862 [ +  - ][ +  - ]:       1036 :                 awt::Point a2DPos = xShape3DAnchor->getPosition(); //get 2D position from xShape3DAnchor
     863 [ +  - ][ +  - ]:       1036 :                 m_xLogicTarget->remove(xShape3DAnchor);
     864                 :       1036 :                 aRet.setX( a2DPos.X );
     865                 :       1036 :                 aRet.setY( a2DPos.Y );
     866                 :            :             }
     867                 :            :             else
     868                 :            :             {
     869                 :            :                 OSL_FAIL("cannot calculate scrren position in VCartesianAxis::getScreenPosition");
     870                 :            :             }
     871                 :            :         }
     872                 :            :         else
     873                 :            :         {
     874                 :      44728 :             aRet.setX( aScenePos.PositionX );
     875                 :      45764 :             aRet.setY( aScenePos.PositionY );
     876                 :            :         }
     877                 :            :     }
     878                 :            : 
     879                 :      45764 :     return aRet;
     880                 :            : }
     881                 :            : 
     882                 :          0 : VCartesianAxis::ScreenPosAndLogicPos VCartesianAxis::getScreenPosAndLogicPos( double fLogicX_, double fLogicY_, double fLogicZ_ ) const
     883                 :            : {
     884                 :          0 :     ScreenPosAndLogicPos aRet;
     885                 :          0 :     aRet.fLogicX = fLogicX_;
     886                 :          0 :     aRet.fLogicY = fLogicY_;
     887                 :          0 :     aRet.fLogicZ = fLogicZ_;
     888 [ #  # ][ #  # ]:          0 :     aRet.aScreenPos = getScreenPosition( fLogicX_, fLogicY_, fLogicZ_ );
     889                 :          0 :     return aRet;
     890                 :            : }
     891                 :            : 
     892                 :            : typedef ::std::vector< VCartesianAxis::ScreenPosAndLogicPos > tScreenPosAndLogicPosList;
     893                 :            : struct lcl_LessXPos : ::std::binary_function< VCartesianAxis::ScreenPosAndLogicPos, VCartesianAxis::ScreenPosAndLogicPos, bool >
     894                 :            : {
     895                 :          0 :     inline bool operator() ( const VCartesianAxis::ScreenPosAndLogicPos& rPos1, const VCartesianAxis::ScreenPosAndLogicPos& rPos2 )
     896                 :            :     {
     897                 :          0 :         return ( rPos1.aScreenPos.getX() < rPos2.aScreenPos.getX() );
     898                 :            :     }
     899                 :            : };
     900                 :            : 
     901                 :            : struct lcl_GreaterYPos : ::std::binary_function< VCartesianAxis::ScreenPosAndLogicPos, VCartesianAxis::ScreenPosAndLogicPos, bool >
     902                 :            : {
     903                 :          0 :     inline bool operator() ( const VCartesianAxis::ScreenPosAndLogicPos& rPos1, const VCartesianAxis::ScreenPosAndLogicPos& rPos2 )
     904                 :            :     {
     905                 :          0 :         return ( rPos1.aScreenPos.getY() > rPos2.aScreenPos.getY() );
     906                 :            :     }
     907                 :            : };
     908                 :            : 
     909                 :      22882 : void VCartesianAxis::get2DAxisMainLine( B2DVector& rStart, B2DVector& rEnd, double fCrossesOtherAxis )
     910                 :            : {
     911                 :            :     //m_aAxisProperties might get updated and changed here because
     912                 :            :     //    the label alignmant and inner direction sign depends exactly of the choice of the axis line position which is made here in this method
     913                 :            : 
     914                 :      22882 :     double fMinX = m_pPosHelper->getLogicMinX();
     915                 :      22882 :     double fMinY = m_pPosHelper->getLogicMinY();
     916                 :      22882 :     double fMinZ = m_pPosHelper->getLogicMinZ();
     917                 :      22882 :     double fMaxX = m_pPosHelper->getLogicMaxX();
     918                 :      22882 :     double fMaxY = m_pPosHelper->getLogicMaxY();
     919                 :      22882 :     double fMaxZ = m_pPosHelper->getLogicMaxZ();
     920                 :            : 
     921                 :      22882 :     double fXStart = fMinX;
     922                 :      22882 :     double fYStart = fMinY;
     923                 :      22882 :     double fZStart = fMinZ;
     924                 :      22882 :     double fXEnd = fXStart;
     925                 :      22882 :     double fYEnd = fYStart;
     926                 :      22882 :     double fZEnd = fZStart;
     927                 :            : 
     928                 :      22882 :     double fXOnXPlane = fMinX;
     929                 :      22882 :     double fXOther = fMaxX;
     930         [ -  + ]:      22882 :     int nDifferentValue = !m_pPosHelper->isMathematicalOrientationX() ? -1 : 1;
     931         [ +  + ]:      22882 :     if( !m_pPosHelper->isSwapXAndY() )
     932         [ -  + ]:      22740 :         nDifferentValue *= (CuboidPlanePosition_Left != m_eLeftWallPos) ? -1 : 1;
     933                 :            :     else
     934         [ -  + ]:        142 :         nDifferentValue *= (CuboidPlanePosition_Bottom != m_eBottomPos) ? -1 : 1;
     935         [ -  + ]:      22882 :     if( nDifferentValue<0 )
     936                 :            :     {
     937                 :          0 :         fXOnXPlane = fMaxX;
     938                 :          0 :         fXOther = fMinX;
     939                 :            :     }
     940                 :            : 
     941                 :      22882 :     double fYOnYPlane = fMinY;
     942                 :      22882 :     double fYOther = fMaxY;
     943         [ +  + ]:      22882 :     nDifferentValue = !m_pPosHelper->isMathematicalOrientationY() ? -1 : 1;
     944         [ +  + ]:      22882 :     if( !m_pPosHelper->isSwapXAndY() )
     945         [ -  + ]:      22740 :         nDifferentValue *= (CuboidPlanePosition_Bottom != m_eBottomPos) ? -1 : 1;
     946                 :            :     else
     947         [ -  + ]:        142 :         nDifferentValue *= (CuboidPlanePosition_Left != m_eLeftWallPos) ? -1 : 1;
     948         [ +  + ]:      22882 :     if( nDifferentValue<0 )
     949                 :            :     {
     950                 :       1115 :         fYOnYPlane = fMaxY;
     951                 :       1115 :         fYOther = fMinY;
     952                 :            :     }
     953                 :            : 
     954                 :      22882 :     double fZOnZPlane = fMaxZ;
     955                 :      22882 :     double fZOther = fMinZ;
     956         [ -  + ]:      22882 :     nDifferentValue = !m_pPosHelper->isMathematicalOrientationZ() ? -1 : 1;
     957         [ -  + ]:      22882 :     nDifferentValue *= (CuboidPlanePosition_Back != m_eBackWallPos) ? -1 : 1;
     958         [ -  + ]:      22882 :     if( nDifferentValue<0 )
     959                 :            :     {
     960                 :          0 :         fZOnZPlane = fMinZ;
     961                 :          0 :         fZOther = fMaxZ;
     962                 :            :     }
     963                 :            : 
     964         [ +  + ]:      22882 :     if( 0==m_nDimensionIndex ) //x-axis
     965                 :            :     {
     966         [ +  + ]:      12504 :         if( fCrossesOtherAxis < fMinY )
     967                 :       2964 :             fCrossesOtherAxis = fMinY;
     968         [ -  + ]:       9540 :         else if( fCrossesOtherAxis > fMaxY )
     969                 :          0 :             fCrossesOtherAxis = fMaxY;
     970                 :            : 
     971                 :      12504 :         fYStart = fYEnd = fCrossesOtherAxis;
     972                 :      12504 :         fXEnd=m_pPosHelper->getLogicMaxX();
     973                 :            : 
     974         [ +  + ]:      12504 :         if(3==m_nDimension)
     975                 :            :         {
     976         [ +  - ]:        182 :             if( AxisHelper::isAxisPositioningEnabled() )
     977                 :            :             {
     978         [ -  + ]:        182 :                 if( ::rtl::math::approxEqual( fYOther, fYStart) )
     979                 :          0 :                     fZStart = fZEnd = fZOnZPlane;
     980                 :            :                 else
     981                 :        182 :                     fZStart = fZEnd = fZOther;
     982                 :            :             }
     983                 :            :             else
     984                 :            :             {
     985 [ #  # ][ #  # ]:          0 :                 rStart = getScreenPosition( fXStart, fYStart, fZStart );
     986 [ #  # ][ #  # ]:          0 :                 rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
     987                 :            : 
     988                 :          0 :                 double fDeltaX = rEnd.getX() - rStart.getX();
     989                 :          0 :                 double fDeltaY = rEnd.getY() - rStart.getY();
     990                 :            : 
     991                 :            :                 //only those points are candidates which are lying on exactly one wall as these are outer edges
     992         [ #  # ]:          0 :                 tScreenPosAndLogicPosList aPosList;
     993 [ #  # ][ #  # ]:          0 :                 aPosList.push_back( getScreenPosAndLogicPos( fMinX, fYOnYPlane, fZOther ) );
     994 [ #  # ][ #  # ]:          0 :                 aPosList.push_back( getScreenPosAndLogicPos( fMinX, fYOther, fZOnZPlane ) );
     995                 :            : 
     996         [ #  # ]:          0 :                 if( fabs(fDeltaY) > fabs(fDeltaX)  )
     997                 :            :                 {
     998                 :          0 :                     m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_LEFT;
     999                 :            :                     //choose most left positions
    1000         [ #  # ]:          0 :                     ::std::sort( aPosList.begin(), aPosList.end(), lcl_LessXPos() );
    1001         [ #  # ]:          0 :                     m_aAxisProperties.m_fLabelDirectionSign = fDeltaY<0 ? -1 : 1;
    1002                 :            :                 }
    1003                 :            :                 else
    1004                 :            :                 {
    1005                 :          0 :                     m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_BOTTOM;
    1006                 :            :                     //choose most bottom positions
    1007         [ #  # ]:          0 :                     ::std::sort( aPosList.begin(), aPosList.end(), lcl_GreaterYPos() );
    1008         [ #  # ]:          0 :                     m_aAxisProperties.m_fLabelDirectionSign = fDeltaX<0 ? -1 : 1;
    1009                 :            :                 }
    1010                 :          0 :                 ScreenPosAndLogicPos aBestPos( aPosList[0] );
    1011                 :          0 :                 fYStart = fYEnd = aBestPos.fLogicY;
    1012                 :          0 :                 fZStart = fZEnd = aBestPos.fLogicZ;
    1013 [ #  # ][ #  # ]:          0 :                 if( !m_pPosHelper->isMathematicalOrientationX() )
    1014                 :          0 :                     m_aAxisProperties.m_fLabelDirectionSign *= -1;
    1015                 :            :             }
    1016                 :            :         }//end 3D x axis
    1017                 :            :     }
    1018         [ +  + ]:      10378 :     else if( 1==m_nDimensionIndex ) //y-axis
    1019                 :            :     {
    1020         [ +  + ]:      10231 :         if( fCrossesOtherAxis < fMinX )
    1021                 :       8616 :             fCrossesOtherAxis = fMinX;
    1022         [ -  + ]:       1615 :         else if( fCrossesOtherAxis > fMaxX )
    1023                 :          0 :             fCrossesOtherAxis = fMaxX;
    1024                 :            : 
    1025                 :      10231 :         fXStart = fXEnd = fCrossesOtherAxis;
    1026                 :      10231 :         fYEnd=m_pPosHelper->getLogicMaxY();
    1027                 :            : 
    1028         [ +  + ]:      10231 :         if(3==m_nDimension)
    1029                 :            :         {
    1030         [ +  - ]:        189 :             if( AxisHelper::isAxisPositioningEnabled() )
    1031                 :            :             {
    1032         [ -  + ]:        189 :                 if( ::rtl::math::approxEqual( fXOther, fXStart) )
    1033                 :          0 :                     fZStart = fZEnd = fZOnZPlane;
    1034                 :            :                 else
    1035                 :        189 :                     fZStart = fZEnd = fZOther;
    1036                 :            :             }
    1037                 :            :             else
    1038                 :            :             {
    1039 [ #  # ][ #  # ]:          0 :                 rStart = getScreenPosition( fXStart, fYStart, fZStart );
    1040 [ #  # ][ #  # ]:          0 :                 rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
    1041                 :            : 
    1042                 :          0 :                 double fDeltaX = rEnd.getX() - rStart.getX();
    1043                 :          0 :                 double fDeltaY = rEnd.getY() - rStart.getY();
    1044                 :            : 
    1045                 :            :                 //only those points are candidates which are lying on exactly one wall as these are outer edges
    1046         [ #  # ]:          0 :                 tScreenPosAndLogicPosList aPosList;
    1047 [ #  # ][ #  # ]:          0 :                 aPosList.push_back( getScreenPosAndLogicPos( fXOnXPlane, fMinY, fZOther ) );
    1048 [ #  # ][ #  # ]:          0 :                 aPosList.push_back( getScreenPosAndLogicPos( fXOther, fMinY, fZOnZPlane ) );
    1049                 :            : 
    1050         [ #  # ]:          0 :                 if( fabs(fDeltaY) > fabs(fDeltaX)  )
    1051                 :            :                 {
    1052                 :          0 :                     m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_LEFT;
    1053                 :            :                     //choose most left positions
    1054         [ #  # ]:          0 :                     ::std::sort( aPosList.begin(), aPosList.end(), lcl_LessXPos() );
    1055         [ #  # ]:          0 :                     m_aAxisProperties.m_fLabelDirectionSign = fDeltaY<0 ? -1 : 1;
    1056                 :            :                 }
    1057                 :            :                 else
    1058                 :            :                 {
    1059                 :          0 :                     m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_BOTTOM;
    1060                 :            :                     //choose most bottom positions
    1061         [ #  # ]:          0 :                     ::std::sort( aPosList.begin(), aPosList.end(), lcl_GreaterYPos() );
    1062         [ #  # ]:          0 :                     m_aAxisProperties.m_fLabelDirectionSign = fDeltaX<0 ? -1 : 1;
    1063                 :            :                 }
    1064                 :          0 :                 ScreenPosAndLogicPos aBestPos( aPosList[0] );
    1065                 :          0 :                 fXStart = fXEnd = aBestPos.fLogicX;
    1066                 :          0 :                 fZStart = fZEnd = aBestPos.fLogicZ;
    1067 [ #  # ][ #  # ]:          0 :                 if( !m_pPosHelper->isMathematicalOrientationY() )
    1068                 :          0 :                     m_aAxisProperties.m_fLabelDirectionSign *= -1;
    1069                 :            :             }
    1070                 :            :         }//end 3D y axis
    1071                 :            :     }
    1072                 :            :     else //z-axis
    1073                 :            :     {
    1074                 :        147 :         fZEnd = m_pPosHelper->getLogicMaxZ();
    1075         [ +  - ]:        147 :         if( AxisHelper::isAxisPositioningEnabled() )
    1076                 :            :         {
    1077         [ +  + ]:        147 :             if( !m_aAxisProperties.m_bSwapXAndY )
    1078                 :            :             {
    1079         [ -  + ]:        109 :                 if( fCrossesOtherAxis < fMinY )
    1080                 :          0 :                     fCrossesOtherAxis = fMinY;
    1081         [ -  + ]:        109 :                 else if( fCrossesOtherAxis > fMaxY )
    1082                 :          0 :                     fCrossesOtherAxis = fMaxY;
    1083                 :        109 :                 fYStart = fYEnd = fCrossesOtherAxis;
    1084                 :            : 
    1085         [ -  + ]:        109 :                 if( ::rtl::math::approxEqual( fYOther, fYStart) )
    1086                 :          0 :                     fXStart = fXEnd = fXOnXPlane;
    1087                 :            :                 else
    1088                 :        109 :                     fXStart = fXEnd = fXOther;
    1089                 :            :             }
    1090                 :            :             else
    1091                 :            :             {
    1092         [ +  - ]:         38 :                 if( fCrossesOtherAxis < fMinX )
    1093                 :         38 :                     fCrossesOtherAxis = fMinX;
    1094         [ #  # ]:          0 :                 else if( fCrossesOtherAxis > fMaxX )
    1095                 :          0 :                     fCrossesOtherAxis = fMaxX;
    1096                 :         38 :                 fXStart = fXEnd = fCrossesOtherAxis;
    1097                 :            : 
    1098         [ -  + ]:         38 :                 if( ::rtl::math::approxEqual( fXOther, fXStart) )
    1099                 :          0 :                     fYStart = fYEnd = fYOnYPlane;
    1100                 :            :                 else
    1101                 :         38 :                     fYStart = fYEnd = fYOther;
    1102                 :            :             }
    1103                 :            :         }
    1104                 :            :         else
    1105                 :            :         {
    1106         [ #  # ]:          0 :             if( !m_pPosHelper->isSwapXAndY() )
    1107                 :            :             {
    1108         [ #  # ]:          0 :                 fXStart = fXEnd = m_pPosHelper->isMathematicalOrientationX() ? m_pPosHelper->getLogicMaxX() : m_pPosHelper->getLogicMinX();
    1109         [ #  # ]:          0 :                 fYStart = fYEnd = m_pPosHelper->isMathematicalOrientationY() ? m_pPosHelper->getLogicMinY() : m_pPosHelper->getLogicMaxY();
    1110                 :            :             }
    1111                 :            :             else
    1112                 :            :             {
    1113         [ #  # ]:          0 :                 fXStart = fXEnd = m_pPosHelper->isMathematicalOrientationX() ? m_pPosHelper->getLogicMinX() : m_pPosHelper->getLogicMaxX();
    1114         [ #  # ]:          0 :                 fYStart = fYEnd = m_pPosHelper->isMathematicalOrientationY() ? m_pPosHelper->getLogicMaxY() : m_pPosHelper->getLogicMinY();
    1115                 :            :             }
    1116                 :            : 
    1117         [ #  # ]:          0 :             if(3==m_nDimension)
    1118                 :            :             {
    1119 [ #  # ][ #  # ]:          0 :                 rStart = getScreenPosition( fXStart, fYStart, fZStart );
    1120 [ #  # ][ #  # ]:          0 :                 rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
    1121                 :            : 
    1122                 :          0 :                 double fDeltaX = rEnd.getX() - rStart.getX();
    1123                 :            : 
    1124                 :            :                 //only those points are candidates which are lying on exactly one wall as these are outer edges
    1125         [ #  # ]:          0 :                 tScreenPosAndLogicPosList aPosList;
    1126 [ #  # ][ #  # ]:          0 :                 aPosList.push_back( getScreenPosAndLogicPos( fXOther, fYOnYPlane, fMinZ ) );
    1127 [ #  # ][ #  # ]:          0 :                 aPosList.push_back( getScreenPosAndLogicPos( fXOnXPlane, fYOther, fMinZ ) );
    1128                 :            : 
    1129         [ #  # ]:          0 :                 ::std::sort( aPosList.begin(), aPosList.end(), lcl_GreaterYPos() );
    1130                 :          0 :                 ScreenPosAndLogicPos aBestPos( aPosList[0] );
    1131                 :          0 :                 ScreenPosAndLogicPos aNotSoGoodPos( aPosList[1] );
    1132                 :            : 
    1133                 :            :                 //choose most bottom positions
    1134         [ #  # ]:          0 :                 if( !::rtl::math::approxEqual( fDeltaX, 0.0 ) ) // prefere left-right algnments
    1135                 :            :                 {
    1136         [ #  # ]:          0 :                     if( aBestPos.aScreenPos.getX() > aNotSoGoodPos.aScreenPos.getX() )
    1137                 :          0 :                         m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_RIGHT;
    1138                 :            :                     else
    1139                 :          0 :                          m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_LEFT;
    1140                 :            :                 }
    1141                 :            :                 else
    1142                 :            :                 {
    1143         [ #  # ]:          0 :                     if( aBestPos.aScreenPos.getY() > aNotSoGoodPos.aScreenPos.getY() )
    1144                 :          0 :                         m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_BOTTOM;
    1145                 :            :                     else
    1146                 :          0 :                          m_aAxisProperties.m_aLabelAlignment = LABEL_ALIGN_TOP;
    1147                 :            :                 }
    1148                 :            : 
    1149         [ #  # ]:          0 :                 m_aAxisProperties.m_fLabelDirectionSign = fDeltaX<0 ? -1 : 1;
    1150 [ #  # ][ #  # ]:          0 :                 if( !m_pPosHelper->isMathematicalOrientationZ() )
    1151                 :          0 :                     m_aAxisProperties.m_fLabelDirectionSign *= -1;
    1152                 :            : 
    1153                 :          0 :                 fXStart = fXEnd = aBestPos.fLogicX;
    1154                 :          0 :                 fYStart = fYEnd = aBestPos.fLogicY;
    1155                 :            :             }
    1156                 :            :         }//end 3D z axis
    1157                 :            :     }
    1158                 :            : 
    1159         [ +  - ]:      22882 :     rStart = getScreenPosition( fXStart, fYStart, fZStart );
    1160         [ +  - ]:      22882 :     rEnd = getScreenPosition( fXEnd, fYEnd, fZEnd );
    1161                 :            : 
    1162 [ -  + ][ -  + ]:      22882 :     if(3==m_nDimension && !AxisHelper::isAxisPositioningEnabled() )
                 [ +  + ]
    1163                 :          0 :         m_aAxisProperties.m_fInnerDirectionSign = m_aAxisProperties.m_fLabelDirectionSign;//to behave like before
    1164                 :            : 
    1165 [ +  + ][ +  - ]:      22882 :     if(3==m_nDimension && AxisHelper::isAxisPositioningEnabled() )
                 [ +  + ]
    1166                 :            :     {
    1167                 :        518 :         double fDeltaX = rEnd.getX() - rStart.getX();
    1168                 :        518 :         double fDeltaY = rEnd.getY() - rStart.getY();
    1169                 :            : 
    1170         [ +  + ]:        518 :         if( 2==m_nDimensionIndex )
    1171                 :            :         {
    1172         [ -  + ]:        147 :             if( m_eLeftWallPos != CuboidPlanePosition_Left )
    1173                 :            :             {
    1174                 :          0 :                 m_aAxisProperties.m_fLabelDirectionSign *= -1.0;
    1175                 :          0 :                 m_aAxisProperties.m_fInnerDirectionSign *= -1.0;
    1176                 :            :             }
    1177                 :            : 
    1178                 :            :             m_aAxisProperties.m_aLabelAlignment =
    1179                 :            :                 ( m_aAxisProperties.m_fLabelDirectionSign<0 ) ?
    1180         [ -  + ]:        147 :                     LABEL_ALIGN_LEFT :  LABEL_ALIGN_RIGHT;
    1181                 :            : 
    1182 [ +  - ][ +  - ]:        147 :             if( ( fDeltaY<0 && m_aScale.Orientation == AxisOrientation_REVERSE ) ||
         [ -  + ][ #  # ]
    1183                 :            :                 ( fDeltaY>0 && m_aScale.Orientation == AxisOrientation_MATHEMATICAL ) )
    1184                 :            :                 m_aAxisProperties.m_aLabelAlignment =
    1185                 :            :                     ( m_aAxisProperties.m_aLabelAlignment==LABEL_ALIGN_RIGHT ) ?
    1186         [ #  # ]:          0 :                         LABEL_ALIGN_LEFT :  LABEL_ALIGN_RIGHT;
    1187                 :            :         }
    1188         [ +  + ]:        371 :         else if( fabs(fDeltaY) > fabs(fDeltaX) )
    1189                 :            :         {
    1190         [ -  + ]:        189 :             if( m_eBackWallPos != CuboidPlanePosition_Back )
    1191                 :            :             {
    1192                 :          0 :                 m_aAxisProperties.m_fLabelDirectionSign *= -1.0;
    1193                 :          0 :                 m_aAxisProperties.m_fInnerDirectionSign *= -1.0;
    1194                 :            :             }
    1195                 :            : 
    1196                 :            :             m_aAxisProperties.m_aLabelAlignment =
    1197                 :            :                 ( m_aAxisProperties.m_fLabelDirectionSign<0 ) ?
    1198         [ +  - ]:        189 :                     LABEL_ALIGN_LEFT :  LABEL_ALIGN_RIGHT;
    1199                 :            : 
    1200 [ +  - ][ +  - ]:        189 :             if( ( fDeltaY<0 && m_aScale.Orientation == AxisOrientation_REVERSE ) ||
         [ -  + ][ #  # ]
    1201                 :            :                 ( fDeltaY>0 && m_aScale.Orientation == AxisOrientation_MATHEMATICAL ) )
    1202                 :            :                 m_aAxisProperties.m_aLabelAlignment =
    1203                 :            :                     ( m_aAxisProperties.m_aLabelAlignment==LABEL_ALIGN_RIGHT ) ?
    1204         [ #  # ]:          0 :                         LABEL_ALIGN_LEFT :  LABEL_ALIGN_RIGHT;
    1205                 :            :         }
    1206                 :            :         else
    1207                 :            :         {
    1208         [ -  + ]:        182 :             if( m_eBackWallPos != CuboidPlanePosition_Back )
    1209                 :            :             {
    1210                 :          0 :                 m_aAxisProperties.m_fLabelDirectionSign *= -1.0;
    1211                 :          0 :                 m_aAxisProperties.m_fInnerDirectionSign *= -1.0;
    1212                 :            :             }
    1213                 :            : 
    1214                 :            :             m_aAxisProperties.m_aLabelAlignment =
    1215                 :            :                 ( m_aAxisProperties.m_fLabelDirectionSign<0 ) ?
    1216         [ -  + ]:        182 :                     LABEL_ALIGN_TOP : LABEL_ALIGN_BOTTOM;
    1217                 :            : 
    1218 [ +  - ][ +  - ]:        182 :             if( ( fDeltaX>0 && m_aScale.Orientation == AxisOrientation_REVERSE ) ||
         [ -  + ][ #  # ]
    1219                 :            :                 ( fDeltaX<0 && m_aScale.Orientation == AxisOrientation_MATHEMATICAL ) )
    1220                 :            :                 m_aAxisProperties.m_aLabelAlignment =
    1221                 :            :                     ( m_aAxisProperties.m_aLabelAlignment==LABEL_ALIGN_TOP ) ?
    1222         [ #  # ]:          0 :                         LABEL_ALIGN_BOTTOM : LABEL_ALIGN_TOP;
    1223                 :            :         }
    1224                 :            :     }
    1225                 :      22882 : }
    1226                 :            : 
    1227                 :       3640 : TickFactory* VCartesianAxis::createTickFactory()
    1228                 :            : {
    1229                 :       3640 :     return createTickFactory2D();
    1230                 :            : }
    1231                 :            : 
    1232                 :      10598 : TickFactory_2D* VCartesianAxis::createTickFactory2D()
    1233                 :            : {
    1234                 :      10598 :     B2DVector aStart, aEnd;
    1235 [ +  - ][ +  - ]:      10598 :     this->get2DAxisMainLine( aStart, aEnd, this->getLogicValueWhereMainLineCrossesOtherAxis() );
    1236                 :            : 
    1237                 :      10598 :     B2DVector aLabelLineStart, aLabelLineEnd;
    1238 [ +  - ][ +  - ]:      10598 :     this->get2DAxisMainLine( aLabelLineStart, aLabelLineEnd, this->getLogicValueWhereLabelLineCrossesOtherAxis() );
    1239                 :            : 
    1240 [ +  - ][ +  - ]:      10598 :     return new TickFactory_2D( m_aScale, m_aIncrement, aStart, aEnd, aLabelLineStart-aStart );
    1241                 :            : }
    1242                 :            : 
    1243                 :       2568 : void lcl_hideIdenticalScreenValues( TickIter& rTickIter )
    1244                 :            : {
    1245                 :       2568 :     TickInfo* pPreviousTickInfo = rTickIter.firstInfo();
    1246         [ -  + ]:       2568 :     if(!pPreviousTickInfo)
    1247                 :       2568 :         return;
    1248                 :       2568 :     pPreviousTickInfo->bPaintIt = true;
    1249         [ +  + ]:      27346 :     for( TickInfo* pTickInfo = rTickIter.nextInfo(); pTickInfo; pTickInfo = rTickIter.nextInfo())
    1250                 :            :     {
    1251                 :            :         pTickInfo->bPaintIt =
    1252                 :      24778 :             ( static_cast<sal_Int32>(pTickInfo->aTickScreenPosition.getX())
    1253                 :      24778 :             != static_cast<sal_Int32>(pPreviousTickInfo->aTickScreenPosition.getX()) )
    1254                 :            :             ||
    1255                 :       9092 :             ( static_cast<sal_Int32>(pTickInfo->aTickScreenPosition.getY())
    1256   [ +  +  +  - ]:      33870 :             != static_cast<sal_Int32>(pPreviousTickInfo->aTickScreenPosition.getY()) );
    1257                 :      24778 :         pPreviousTickInfo = pTickInfo;
    1258                 :            :     }
    1259                 :            : }
    1260                 :            : 
    1261                 :            : //'hide' tickmarks with identical screen values in aAllTickInfos
    1262                 :       2568 : void VCartesianAxis::hideIdenticalScreenValues( ::std::vector< ::std::vector< TickInfo > >& rTickInfos ) const
    1263                 :            : {
    1264 [ +  - ][ -  + ]:       2568 :     if( isComplexCategoryAxis() || isDateAxis() )
                 [ -  + ]
    1265                 :            :     {
    1266                 :          0 :         sal_Int32 nCount = rTickInfos.size();
    1267         [ #  # ]:          0 :         for( sal_Int32 nN=0; nN<nCount; nN++ )
    1268                 :            :         {
    1269         [ #  # ]:          0 :             PureTickIter aTickIter( rTickInfos[nN] );
    1270         [ #  # ]:          0 :             lcl_hideIdenticalScreenValues( aTickIter );
    1271         [ #  # ]:          0 :         }
    1272                 :            :     }
    1273                 :            :     else
    1274                 :            :     {
    1275         [ +  - ]:       2568 :         EquidistantTickIter aTickIter( rTickInfos, m_aIncrement, 0, -1 );
    1276 [ +  - ][ +  - ]:       2568 :         lcl_hideIdenticalScreenValues( aTickIter );
    1277                 :            :     }
    1278                 :       2568 : }
    1279                 :            : 
    1280                 :       3890 : sal_Int32 VCartesianAxis::estimateMaximumAutoMainIncrementCount()
    1281                 :            : {
    1282                 :       3890 :     sal_Int32 nRet = 10;
    1283                 :            : 
    1284 [ +  + ][ +  - ]:       3890 :     if( m_nMaximumTextWidthSoFar==0 && m_nMaximumTextHeightSoFar==0 )
    1285                 :       2204 :         return nRet;
    1286                 :            : 
    1287                 :       1686 :     B2DVector aStart, aEnd;
    1288 [ +  - ][ +  - ]:       1686 :     this->get2DAxisMainLine( aStart, aEnd, this->getLogicValueWhereMainLineCrossesOtherAxis() );
    1289                 :            : 
    1290                 :       1686 :     sal_Int32 nMaxHeight = static_cast<sal_Int32>(fabs(aEnd.getY()-aStart.getY()));
    1291                 :       1686 :     sal_Int32 nMaxWidth = static_cast<sal_Int32>(fabs(aEnd.getX()-aStart.getX()));
    1292                 :            : 
    1293                 :       1686 :     sal_Int32 nTotalAvailable = nMaxHeight;
    1294                 :       1686 :     sal_Int32 nSingleNeeded = m_nMaximumTextHeightSoFar;
    1295                 :            : 
    1296                 :            :     //for horizontal axis:
    1297 [ +  + ][ +  + ]:       1686 :     if( (m_nDimensionIndex == 0 && !m_aAxisProperties.m_bSwapXAndY)
         [ +  + ][ +  + ]
    1298                 :            :         || (m_nDimensionIndex == 1 && m_aAxisProperties.m_bSwapXAndY) )
    1299                 :            :     {
    1300                 :        960 :         nTotalAvailable = nMaxWidth;
    1301                 :        960 :         nSingleNeeded = m_nMaximumTextWidthSoFar;
    1302                 :            :     }
    1303                 :            : 
    1304         [ +  - ]:       1686 :     if( nSingleNeeded>0 )
    1305                 :       1686 :         nRet = nTotalAvailable/nSingleNeeded;
    1306                 :            : 
    1307                 :       3890 :     return nRet;
    1308                 :            : }
    1309                 :            : 
    1310                 :       5138 : void VCartesianAxis::doStaggeringOfLabels( const AxisLabelProperties& rAxisLabelProperties, TickFactory_2D* pTickFactory2D )
    1311                 :            : {
    1312         [ -  + ]:       5138 :     if( !pTickFactory2D )
    1313                 :       5138 :         return;
    1314                 :            : 
    1315         [ -  + ]:       5138 :     if( isComplexCategoryAxis() )
    1316                 :            :     {
    1317         [ #  # ]:          0 :         sal_Int32 nTextLevelCount = getTextLevelCount();
    1318                 :          0 :         B2DVector aCummulatedLabelsDistance(0,0);
    1319         [ #  # ]:          0 :         for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
    1320                 :            :         {
    1321         [ #  # ]:          0 :             boost::scoped_ptr< TickIter > apTickIter(createLabelTickIterator( nTextLevel ));
    1322         [ #  # ]:          0 :             if(apTickIter)
    1323                 :            :             {
    1324                 :          0 :                 double fRotationAngleDegree = m_aAxisLabelProperties.fRotationAngleDegree;
    1325                 :          0 :                 aCummulatedLabelsDistance += lcl_getLabelsDistance( *apTickIter.get()
    1326                 :            :                         , pTickFactory2D->getDistanceAxisTickToText( m_aAxisProperties )
    1327   [ #  #  #  # ]:          0 :                         , fRotationAngleDegree );
    1328                 :            :             }
    1329         [ #  # ]:          0 :         }
    1330                 :            :     }
    1331         [ +  + ]:       5138 :     else if( rAxisLabelProperties.getIsStaggered() )
    1332                 :            :     {
    1333         [ +  + ]:        949 :         if( !m_aAllTickInfos.empty() )
    1334                 :            :         {
    1335         [ +  - ]:        892 :             LabelIterator aInnerIter( m_aAllTickInfos[0], rAxisLabelProperties.eStaggering, true );
    1336         [ +  - ]:        892 :             LabelIterator aOuterIter( m_aAllTickInfos[0], rAxisLabelProperties.eStaggering, false );
    1337                 :            : 
    1338                 :            :             lcl_shiftLables( aOuterIter
    1339                 :            :                 , lcl_getLabelsDistance( aInnerIter
    1340 [ +  - ][ +  - ]:        892 :                     , pTickFactory2D->getDistanceAxisTickToText( m_aAxisProperties ), 0.0 ) );
         [ +  - ][ +  - ]
                 [ +  - ]
    1341                 :            :         }
    1342                 :            :     }
    1343                 :            : }
    1344                 :            : 
    1345                 :       1938 : void VCartesianAxis::createLabels()
    1346                 :            : {
    1347         [ +  + ]:       1938 :     if( !prepareShapeCreation() )
    1348                 :        118 :         return;
    1349                 :            : 
    1350                 :            :     //-----------------------------------------
    1351                 :            :     //create labels
    1352         [ +  + ]:       1820 :     if( m_aAxisProperties.m_bDisplayLabels )
    1353                 :            :     {
    1354         [ +  - ]:       1681 :         boost::scoped_ptr< TickFactory_2D > apTickFactory2D( this->createTickFactory2D() );
    1355                 :       1681 :         TickFactory_2D* pTickFactory2D = apTickFactory2D.get();
    1356         [ -  + ]:       1681 :         if( !pTickFactory2D )
    1357                 :            :             return;
    1358                 :            : 
    1359                 :            :         //-----------------------------------------
    1360                 :            :         //get the transformed screen values for all tickmarks in aAllTickInfos
    1361         [ +  - ]:       1681 :         pTickFactory2D->updateScreenValues( m_aAllTickInfos );
    1362                 :            :         //-----------------------------------------
    1363                 :            :         //'hide' tickmarks with identical screen values in aAllTickInfos
    1364         [ +  - ]:       1681 :         hideIdenticalScreenValues( m_aAllTickInfos );
    1365                 :            : 
    1366         [ +  - ]:       1681 :         removeTextShapesFromTicks();
    1367                 :            : 
    1368                 :            :         //create tick mark text shapes
    1369         [ +  - ]:       1681 :         sal_Int32 nTextLevelCount = getTextLevelCount();
    1370                 :       1681 :         sal_Int32 nScreenDistanceBetweenTicks = -1;
    1371         [ +  + ]:       3362 :         for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
    1372                 :            :         {
    1373         [ +  - ]:       1681 :             boost::scoped_ptr< TickIter > apTickIter(createLabelTickIterator( nTextLevel ));
    1374         [ +  - ]:       1681 :             if(apTickIter)
    1375                 :            :             {
    1376         [ +  - ]:       1681 :                 if(nTextLevel==0)
    1377                 :            :                 {
    1378         [ +  - ]:       1681 :                     nScreenDistanceBetweenTicks = TickFactory_2D::getTickScreenDistance( *apTickIter.get() );
    1379         [ -  + ]:       1681 :                     if( nTextLevelCount>1 )
    1380                 :          0 :                         nScreenDistanceBetweenTicks*=2; //the above used tick iter does contain also the sub ticks -> thus the given distance is only the half
    1381                 :            :                 }
    1382                 :            : 
    1383                 :       1681 :                 AxisLabelProperties aComplexProps(m_aAxisLabelProperties);
    1384         [ -  + ]:       1681 :                 if( m_aAxisProperties.m_bComplexCategories )
    1385                 :            :                 {
    1386                 :          0 :                     aComplexProps.bLineBreakAllowed = true;
    1387                 :          0 :                     aComplexProps.bOverlapAllowed = !::rtl::math::approxEqual( aComplexProps.fRotationAngleDegree, 0.0 );
    1388                 :            : 
    1389                 :            :                 }
    1390         [ -  + ]:       1681 :                 AxisLabelProperties& rAxisLabelProperties =  m_aAxisProperties.m_bComplexCategories ? aComplexProps : m_aAxisLabelProperties;
    1391 [ +  - ][ +  + ]:       1739 :                 while( !createTextShapes( m_xTextTarget, *apTickIter.get(), rAxisLabelProperties, pTickFactory2D, nScreenDistanceBetweenTicks ) )
    1392                 :            :                 {
    1393                 :            :                 };
    1394                 :            :             }
    1395         [ +  - ]:       1681 :         }
    1396 [ +  - ][ +  - ]:       1938 :         doStaggeringOfLabels( m_aAxisLabelProperties, pTickFactory2D );
                 [ +  - ]
    1397                 :            :     }
    1398                 :            : }
    1399                 :            : 
    1400                 :       1938 : void VCartesianAxis::createMaximumLabels()
    1401                 :            : {
    1402         [ +  - ]:       1938 :     TrueGuard aRecordMaximumTextSize(m_bRecordMaximumTextSize);
    1403                 :            : 
    1404 [ +  - ][ +  + ]:       1938 :     if( !prepareShapeCreation() )
    1405                 :            :         return;
    1406                 :            : 
    1407                 :            :     //-----------------------------------------
    1408                 :            :     //create labels
    1409         [ +  + ]:       1820 :     if( m_aAxisProperties.m_bDisplayLabels )
    1410                 :            :     {
    1411         [ +  - ]:       1681 :         boost::scoped_ptr< TickFactory_2D > apTickFactory2D( this->createTickFactory2D() );
    1412                 :       1681 :         TickFactory_2D* pTickFactory2D = apTickFactory2D.get();
    1413         [ -  + ]:       1681 :         if( !pTickFactory2D )
    1414                 :            :             return;
    1415                 :            : 
    1416                 :            :         //-----------------------------------------
    1417                 :            :         //get the transformed screen values for all tickmarks in aAllTickInfos
    1418         [ +  - ]:       1681 :         pTickFactory2D->updateScreenValues( m_aAllTickInfos );
    1419                 :            : 
    1420                 :            :         //create tick mark text shapes
    1421                 :            :         //@todo: iterate through all tick depth wich should be labeled
    1422                 :            : 
    1423                 :       1681 :         AxisLabelProperties aAxisLabelProperties( m_aAxisLabelProperties );
    1424 [ +  - ][ +  - ]:       1681 :         if( isAutoStaggeringOfLabelsAllowed( aAxisLabelProperties, pTickFactory2D->isHorizontalAxis(), pTickFactory2D->isVerticalAxis() ) )
                 [ +  + ]
    1425                 :        856 :             aAxisLabelProperties.eStaggering = STAGGER_EVEN;
    1426                 :       1681 :         aAxisLabelProperties.bOverlapAllowed = true;
    1427                 :       1681 :         aAxisLabelProperties.bLineBreakAllowed = false;
    1428         [ +  - ]:       1681 :         sal_Int32 nTextLevelCount = getTextLevelCount();
    1429         [ +  + ]:       3362 :         for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
    1430                 :            :         {
    1431         [ +  - ]:       1681 :             boost::scoped_ptr< TickIter > apTickIter(createMaximumLabelTickIterator( nTextLevel ));
    1432         [ +  - ]:       1681 :             if(apTickIter)
    1433                 :            :             {
    1434 [ +  - ][ -  + ]:       1681 :                 while( !createTextShapes( m_xTextTarget, *apTickIter.get(), aAxisLabelProperties, pTickFactory2D, -1 ) )
    1435                 :            :                 {
    1436                 :            :                 };
    1437                 :            :             }
    1438         [ +  - ]:       1681 :         }
    1439 [ +  - ][ +  - ]:       1820 :         doStaggeringOfLabels( aAxisLabelProperties, pTickFactory2D );
                 [ +  - ]
    1440 [ +  - ][ +  + ]:       1938 :     }
    1441                 :            : }
    1442                 :            : 
    1443                 :       1938 : void VCartesianAxis::updatePositions()
    1444                 :            : {
    1445                 :            :     //-----------------------------------------
    1446                 :            :     //update positions of labels
    1447         [ +  + ]:       1938 :     if( m_aAxisProperties.m_bDisplayLabels )
    1448                 :            :     {
    1449         [ +  - ]:       1776 :         boost::scoped_ptr< TickFactory_2D > apTickFactory2D( this->createTickFactory2D() );
    1450                 :       1776 :         TickFactory_2D* pTickFactory2D = apTickFactory2D.get();
    1451         [ -  + ]:       1776 :         if( !pTickFactory2D )
    1452                 :       1938 :             return;
    1453                 :            : 
    1454                 :            :         //-----------------------------------------
    1455                 :            :         //update positions of all existing text shapes
    1456         [ +  - ]:       1776 :         pTickFactory2D->updateScreenValues( m_aAllTickInfos );
    1457                 :            : 
    1458                 :       1776 :         ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = m_aAllTickInfos.begin();
    1459         [ +  - ]:       1776 :         const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = m_aAllTickInfos.end();
    1460 [ +  - ][ +  + ]:       5138 :         for( sal_Int32 nDepth=0; aDepthIter != aDepthEnd; ++aDepthIter, nDepth++ )
    1461                 :            :         {
    1462                 :       3362 :             ::std::vector< TickInfo >::iterator aTickIter = aDepthIter->begin();
    1463         [ +  - ]:       3362 :             const ::std::vector< TickInfo >::const_iterator aTickEnd  = aDepthIter->end();
    1464 [ +  - ][ +  + ]:      22759 :             for( ; aTickIter != aTickEnd; ++aTickIter )
    1465                 :            :             {
    1466                 :      19397 :                 TickInfo& rTickInfo = (*aTickIter);
    1467                 :      19397 :                 Reference< drawing::XShape > xShape2DText( rTickInfo.xTextShape );
    1468         [ +  + ]:      19397 :                 if( xShape2DText.is() )
    1469                 :            :                 {
    1470         [ +  - ]:       9258 :                     B2DVector aTextToTickDistance( pTickFactory2D->getDistanceAxisTickToText( m_aAxisProperties, true ) );
    1471                 :       9258 :                     B2DVector aTickScreenPos2D( rTickInfo.aTickScreenPosition );
    1472                 :       9258 :                     aTickScreenPos2D += aTextToTickDistance;
    1473                 :            :                     awt::Point aAnchorScreenPosition2D(
    1474                 :       9258 :                         static_cast<sal_Int32>(aTickScreenPos2D.getX())
    1475                 :      18516 :                         ,static_cast<sal_Int32>(aTickScreenPos2D.getY()));
    1476                 :            : 
    1477                 :       9258 :                     double fRotationAngleDegree = m_aAxisLabelProperties.fRotationAngleDegree;
    1478                 :            : 
    1479                 :            :                     // #i78696# use mathematically correct rotation now
    1480                 :       9258 :                     const double fRotationAnglePi(fRotationAngleDegree * (F_PI / -180.0));
    1481         [ +  - ]:       9258 :                     uno::Any aATransformation = ShapeFactory::makeTransformation(aAnchorScreenPosition2D, fRotationAnglePi);
    1482                 :            : 
    1483                 :            :                     //set new position
    1484         [ +  - ]:       9258 :                     uno::Reference< beans::XPropertySet > xProp( xShape2DText, uno::UNO_QUERY );
    1485         [ +  - ]:       9258 :                     if( xProp.is() )
    1486                 :            :                     {
    1487                 :            :                         try
    1488                 :            :                         {
    1489 [ +  - ][ +  - ]:       9258 :                             xProp->setPropertyValue( C2U( "Transformation" ), aATransformation );
         [ +  - ][ #  # ]
    1490                 :            :                         }
    1491         [ #  # ]:          0 :                         catch( const uno::Exception& e )
    1492                 :            :                         {
    1493                 :            :                             ASSERT_EXCEPTION( e );
    1494                 :            :                         }
    1495                 :            :                     }
    1496                 :            : 
    1497                 :            :                     //correctPositionForRotation
    1498                 :            :                     LabelPositionHelper::correctPositionForRotation( xShape2DText
    1499         [ +  - ]:       9258 :                         , m_aAxisProperties.m_aLabelAlignment, fRotationAngleDegree, m_aAxisProperties.m_bComplexCategories );
    1500                 :            :                 }
    1501                 :      19397 :             }
    1502                 :            :         }
    1503                 :            : 
    1504 [ +  - ][ +  - ]:       1776 :         doStaggeringOfLabels( m_aAxisLabelProperties, pTickFactory2D );
                 [ +  - ]
    1505                 :            :     }
    1506                 :            : }
    1507                 :            : 
    1508                 :       1928 : void VCartesianAxis::createTickMarkLineShapes( ::std::vector< TickInfo >& rTickInfos, const TickmarkProperties& rTickmarkProperties, TickFactory_2D& rTickFactory2D, bool bOnlyAtLabels )
    1509                 :            : {
    1510                 :       1928 :     sal_Int32 nPointCount = rTickInfos.size();
    1511         [ +  - ]:       1928 :     drawing::PointSequenceSequence aPoints(2*nPointCount);
    1512                 :            : 
    1513         [ +  - ]:       1928 :     ::std::vector< TickInfo >::const_iterator       aTickIter = rTickInfos.begin();
    1514         [ +  - ]:       1928 :     const ::std::vector< TickInfo >::const_iterator aTickEnd  = rTickInfos.end();
    1515                 :       1928 :     sal_Int32 nN = 0;
    1516 [ +  - ][ +  + ]:      13867 :     for( ; aTickIter != aTickEnd; ++aTickIter )
    1517                 :            :     {
    1518         [ -  + ]:      11939 :         if( !(*aTickIter).bPaintIt )
    1519                 :          0 :             continue;
    1520                 :            : 
    1521                 :      11939 :         bool bTicksAtLabels = ( m_aAxisProperties.m_eTickmarkPos != ::com::sun::star::chart::ChartAxisMarkPosition_AT_AXIS );
    1522                 :      11939 :         double fInnerDirectionSign = m_aAxisProperties.m_fInnerDirectionSign;
    1523 [ +  + ][ -  + ]:      11939 :         if( bTicksAtLabels && m_aAxisProperties.m_eLabelPos == ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END )
    1524                 :          0 :             fInnerDirectionSign *= -1.0;
    1525 [ +  + ][ -  + ]:      11939 :         bTicksAtLabels = bTicksAtLabels || bOnlyAtLabels;
    1526                 :            :         //add ticks at labels:
    1527                 :      11939 :         rTickFactory2D.addPointSequenceForTickLine( aPoints, nN++, (*aTickIter).fScaledTickValue
    1528         [ +  - ]:      11939 :             , fInnerDirectionSign , rTickmarkProperties, bTicksAtLabels );
    1529                 :            :         //add ticks at axis (without lables):
    1530 [ +  - ][ +  + ]:      11939 :         if( !bOnlyAtLabels && m_aAxisProperties.m_eTickmarkPos == ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS )
    1531                 :      10265 :             rTickFactory2D.addPointSequenceForTickLine( aPoints, nN++, (*aTickIter).fScaledTickValue
    1532         [ +  - ]:      10265 :                 , m_aAxisProperties.m_fInnerDirectionSign, rTickmarkProperties, !bTicksAtLabels );
    1533                 :            :     }
    1534         [ +  - ]:       1928 :     aPoints.realloc(nN);
    1535                 :            :     m_pShapeFactory->createLine2D( m_xGroupShape_Shapes, aPoints
    1536 [ +  - ][ +  - ]:       1928 :                                 , &rTickmarkProperties.aLineProperties );
    1537                 :       1928 : }
    1538                 :            : 
    1539                 :       1938 : void VCartesianAxis::createShapes()
    1540                 :            : {
    1541 [ +  - ][ +  + ]:       1938 :     if( !prepareShapeCreation() )
    1542                 :            :         return;
    1543                 :            : 
    1544         [ +  - ]:       1820 :     boost::scoped_ptr< TickFactory_2D > apTickFactory2D( this->createTickFactory2D() );
    1545                 :       1820 :     TickFactory_2D* pTickFactory2D = apTickFactory2D.get();
    1546         [ -  + ]:       1820 :     if( !pTickFactory2D )
    1547                 :            :         return;
    1548                 :            : 
    1549                 :            :     //-----------------------------------------
    1550                 :            :     //create line shapes
    1551         [ +  + ]:       1820 :     if(2==m_nDimension)
    1552                 :            :     {
    1553                 :            :         //-----------------------------------------
    1554                 :            :         //create extra long ticks to separate complex categories (create them only there where the labels are)
    1555 [ +  - ][ -  + ]:       1778 :         if( isComplexCategoryAxis() )
    1556                 :            :         {
    1557         [ #  # ]:          0 :             ::std::vector< ::std::vector< TickInfo > > aComplexTickInfos;
    1558         [ #  # ]:          0 :             createAllTickInfosFromComplexCategories( aComplexTickInfos, true );
    1559         [ #  # ]:          0 :             pTickFactory2D->updateScreenValues( aComplexTickInfos );
    1560         [ #  # ]:          0 :             hideIdenticalScreenValues( aComplexTickInfos );
    1561                 :            : 
    1562         [ #  # ]:          0 :             ::std::vector<TickmarkProperties> aTickmarkPropertiesList;
    1563                 :            :             static bool bIncludeSpaceBetweenTickAndText = false;
    1564 [ #  # ][ #  # ]:          0 :             sal_Int32 nOffset = static_cast<sal_Int32>(pTickFactory2D->getDistanceAxisTickToText( m_aAxisProperties, false, bIncludeSpaceBetweenTickAndText ).getLength());
    1565         [ #  # ]:          0 :             sal_Int32 nTextLevelCount = getTextLevelCount();
    1566         [ #  # ]:          0 :             for( sal_Int32 nTextLevel=0; nTextLevel<nTextLevelCount; nTextLevel++ )
    1567                 :            :             {
    1568         [ #  # ]:          0 :                 boost::scoped_ptr< TickIter > apTickIter(createLabelTickIterator( nTextLevel ));
    1569         [ #  # ]:          0 :                 if( apTickIter )
    1570                 :            :                 {
    1571                 :          0 :                     double fRotationAngleDegree = m_aAxisLabelProperties.fRotationAngleDegree;
    1572 [ #  # ][ #  # ]:          0 :                     B2DVector aLabelsDistance( lcl_getLabelsDistance( *apTickIter.get(), pTickFactory2D->getDistanceAxisTickToText( m_aAxisProperties, false ), fRotationAngleDegree ) );
    1573         [ #  # ]:          0 :                     sal_Int32 nCurrentLength = static_cast<sal_Int32>(aLabelsDistance.getLength());
    1574 [ #  # ][ #  # ]:          0 :                     aTickmarkPropertiesList.push_back( m_aAxisProperties.makeTickmarkPropertiesForComplexCategories( nOffset + nCurrentLength, 0, nTextLevel ) );
    1575                 :          0 :                     nOffset += nCurrentLength;
    1576                 :            :                 }
    1577         [ #  # ]:          0 :             }
    1578                 :            : 
    1579                 :          0 :             sal_Int32 nTickmarkPropertiesCount = aTickmarkPropertiesList.size();
    1580                 :          0 :             ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter             = aComplexTickInfos.begin();
    1581         [ #  # ]:          0 :             const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = aComplexTickInfos.end();
    1582 [ #  # ][ #  # ]:          0 :             for( sal_Int32 nDepth=0; aDepthIter != aDepthEnd && nDepth < nTickmarkPropertiesCount; ++aDepthIter, nDepth++ )
         [ #  # ][ #  # ]
    1583                 :            :             {
    1584 [ #  # ][ #  # ]:          0 :                 if(nDepth==0 && !m_aAxisProperties.m_nMajorTickmarks)
    1585                 :          0 :                     continue;
    1586         [ #  # ]:          0 :                 createTickMarkLineShapes( *aDepthIter, aTickmarkPropertiesList[nDepth], *pTickFactory2D, true /*bOnlyAtLabels*/ );
    1587                 :          0 :             }
    1588                 :            :         }
    1589                 :            :         //-----------------------------------------
    1590                 :            :         //create normal ticks for major and minor intervals
    1591                 :            :         {
    1592         [ +  - ]:       1778 :             ::std::vector< ::std::vector< TickInfo > > aUnshiftedTickInfos;
    1593         [ +  + ]:       1778 :             if( m_aScale.ShiftedCategoryPosition )// if ShiftedCategoryPosition==true the tickmarks in m_aAllTickInfos are shifted
    1594                 :            :             {
    1595         [ +  - ]:        887 :                 pTickFactory2D->getAllTicks( aUnshiftedTickInfos );
    1596         [ +  - ]:        887 :                 pTickFactory2D->updateScreenValues( aUnshiftedTickInfos );
    1597         [ +  - ]:        887 :                 hideIdenticalScreenValues( aUnshiftedTickInfos );
    1598                 :            :             }
    1599         [ +  + ]:       1778 :             ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos = m_aScale.ShiftedCategoryPosition ? aUnshiftedTickInfos : m_aAllTickInfos;
    1600                 :            : 
    1601                 :       1778 :             ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter             = rAllTickInfos.begin();
    1602         [ +  - ]:       1778 :             const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd  = rAllTickInfos.end();
    1603 [ +  - ][ -  + ]:       1778 :             if(aDepthIter == aDepthEnd)//no tickmarks at all
    1604                 :            :                 return;
    1605                 :            : 
    1606                 :       1778 :             sal_Int32 nTickmarkPropertiesCount = m_aAxisProperties.m_aTickmarkPropertiesList.size();
    1607 [ +  - ][ +  + ]:       3706 :             for( sal_Int32 nDepth=0; aDepthIter != aDepthEnd && nDepth < nTickmarkPropertiesCount; ++aDepthIter, nDepth++ )
         [ +  + ][ +  + ]
    1608 [ +  - ][ +  - ]:       3706 :                 createTickMarkLineShapes( *aDepthIter, m_aAxisProperties.m_aTickmarkPropertiesList[nDepth], *pTickFactory2D, false /*bOnlyAtLabels*/ );
    1609                 :            :         }
    1610                 :            :         //-----------------------------------------
    1611                 :            :         //create axis main lines
    1612                 :            :         //it serves also as the handle shape for the axis selection
    1613                 :            :         {
    1614         [ +  - ]:       1778 :             drawing::PointSequenceSequence aPoints(1);
    1615         [ +  - ]:       1778 :             apTickFactory2D->createPointSequenceForAxisMainLine( aPoints );
    1616                 :            :             Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
    1617                 :            :                     m_xGroupShape_Shapes, aPoints
    1618         [ +  - ]:       1778 :                     , &m_aAxisProperties.m_aLineProperties );
    1619                 :            :             //because of this name this line will be used for marking the axis
    1620 [ +  - ][ +  - ]:       1778 :             m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") );
                 [ +  - ]
    1621                 :            :         }
    1622                 :            :         //-----------------------------------------
    1623                 :            :         //create an additional line at NULL
    1624 [ +  - ][ -  + ]:       1778 :         if( !AxisHelper::isAxisPositioningEnabled() )
    1625                 :            :         {
    1626                 :            :             double fExtraLineCrossesOtherAxis;
    1627 [ #  # ][ #  # ]:          0 :             if( getLogicValueWhereExtraLineCrossesOtherAxis(fExtraLineCrossesOtherAxis) )
    1628                 :            :             {
    1629                 :          0 :                 B2DVector aStart, aEnd;
    1630         [ #  # ]:          0 :                 this->get2DAxisMainLine( aStart, aEnd, fExtraLineCrossesOtherAxis );
    1631         [ #  # ]:          0 :                 drawing::PointSequenceSequence aPoints( lcl_makePointSequence(aStart,aEnd) );
    1632                 :            :                 Reference< drawing::XShape > xShape = m_pShapeFactory->createLine2D(
    1633 [ #  # ][ #  # ]:       1820 :                         m_xGroupShape_Shapes, aPoints, &m_aAxisProperties.m_aLineProperties );
    1634                 :            :             }
    1635                 :            :         }
    1636 [ +  - ][ +  - ]:       1938 :     }
    1637                 :            : 
    1638                 :            :     //createLabels();
    1639                 :            : }
    1640                 :            : 
    1641                 :            : //.............................................................................
    1642                 :            : } //namespace chart
    1643                 :            : //.............................................................................
    1644                 :            : 
    1645                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10