fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / chart2 / source / view / axes / VAxisProperties.cxx
blob3db365d5b04f3c6f001db37423c5fa492b5c4026
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "VAxisProperties.hxx"
21 #include "macros.hxx"
22 #include "ViewDefines.hxx"
23 #include "CommonConverters.hxx"
24 #include "AxisHelper.hxx"
25 #include "DiagramHelper.hxx"
26 #include "ChartModelHelper.hxx"
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp>
30 #include <com/sun/star/drawing/LineStyle.hpp>
31 #include <com/sun/star/text/WritingMode2.hpp>
33 using namespace ::com::sun::star;
34 using namespace ::com::sun::star::chart2;
36 namespace chart {
38 AxisLabelAlignment::AxisLabelAlignment() :
39 mfLabelDirection(1.0),
40 mfInnerTickDirection(1.0),
41 meAlignment(LABEL_ALIGN_RIGHT_TOP) {}
43 sal_Int32 lcl_calcTickLengthForDepth(sal_Int32 nDepth,sal_Int32 nTickmarkStyle)
45 sal_Int32 nWidth = AXIS2D_TICKLENGTH; //@maybefuturetodo this length could be offered by the model
46 double fPercent = 1.0;
47 switch(nDepth)
49 case 0:
50 fPercent = 1.0;
51 break;
52 case 1:
53 fPercent = 0.75;//percentage like in the old chart
54 break;
55 case 2:
56 fPercent = 0.5;
57 break;
58 default:
59 fPercent = 0.3;
60 break;
62 if(nTickmarkStyle==3)//inner and outer tickmarks
63 fPercent*=2.0;
64 return static_cast<sal_Int32>(nWidth*fPercent);
67 double lcl_getTickOffset(sal_Int32 nLength,sal_Int32 nTickmarkStyle)
69 double fPercent = 0.0; //0<=fPercent<=1
70 //0.0: completely inner
71 //1.0: completely outer
72 //0.5: half and half
75 nTickmarkStyle:
76 1: inner tickmarks
77 2: outer tickmarks
78 3: inner and outer tickmarks
80 switch(nTickmarkStyle)
82 case 1:
83 fPercent = 0.0;
84 break;
85 case 2:
86 fPercent = 1.0;
87 break;
88 default:
89 fPercent = 0.5;
90 break;
92 return fPercent*nLength;
95 TickmarkProperties AxisProperties::makeTickmarkProperties(
96 sal_Int32 nDepth ) const
99 nTickmarkStyle:
100 1: inner tickmarks
101 2: outer tickmarks
102 3: inner and outer tickmarks
104 sal_Int32 nTickmarkStyle = 1;
105 if(nDepth==0)
107 nTickmarkStyle = m_nMajorTickmarks;
108 if(!nTickmarkStyle)
110 //create major tickmarks as if they were minor tickmarks
111 nDepth = 1;
112 nTickmarkStyle = m_nMinorTickmarks;
115 else if( nDepth==1)
117 nTickmarkStyle = m_nMinorTickmarks;
120 if (maLabelAlignment.mfInnerTickDirection == 0.0)
122 if( nTickmarkStyle != 0 )
123 nTickmarkStyle = 3; //inner and outer tickmarks
126 TickmarkProperties aTickmarkProperties;
127 aTickmarkProperties.Length = lcl_calcTickLengthForDepth(nDepth,nTickmarkStyle);
128 aTickmarkProperties.RelativePos = static_cast<sal_Int32>(lcl_getTickOffset(aTickmarkProperties.Length,nTickmarkStyle));
129 aTickmarkProperties.aLineProperties = this->makeLinePropertiesForDepth( nDepth );
130 return aTickmarkProperties;
133 TickmarkProperties AxisProperties::makeTickmarkPropertiesForComplexCategories(
134 sal_Int32 nTickLength, sal_Int32 nTickStartDistanceToAxis, sal_Int32 /*nTextLevel*/ ) const
136 sal_Int32 nTickmarkStyle = (maLabelAlignment.mfLabelDirection == maLabelAlignment.mfInnerTickDirection) ? 2/*outside*/ : 1/*inside*/;
138 TickmarkProperties aTickmarkProperties;
139 aTickmarkProperties.Length = nTickLength;// + nTextLevel*( lcl_calcTickLengthForDepth(0,nTickmarkStyle) );
140 aTickmarkProperties.RelativePos = static_cast<sal_Int32>(lcl_getTickOffset(aTickmarkProperties.Length+nTickStartDistanceToAxis,nTickmarkStyle));
141 aTickmarkProperties.aLineProperties = this->makeLinePropertiesForDepth( 0 );
142 return aTickmarkProperties;
145 TickmarkProperties AxisProperties::getBiggestTickmarkProperties()
147 TickmarkProperties aTickmarkProperties;
148 sal_Int32 nDepth = 0;
149 sal_Int32 nTickmarkStyle = 3;//inner and outer tickmarks
150 aTickmarkProperties.Length = lcl_calcTickLengthForDepth( nDepth,nTickmarkStyle );
151 aTickmarkProperties.RelativePos = static_cast<sal_Int32>( lcl_getTickOffset( aTickmarkProperties.Length, nTickmarkStyle ) );
152 return aTickmarkProperties;
155 AxisProperties::AxisProperties( const uno::Reference< XAxis >& xAxisModel
156 , ExplicitCategoriesProvider* pExplicitCategoriesProvider )
157 : m_xAxisModel(xAxisModel)
158 , m_nDimensionIndex(0)
159 , m_bIsMainAxis(true)
160 , m_bSwapXAndY(false)
161 , m_eCrossoverType( ::com::sun::star::chart::ChartAxisPosition_ZERO )
162 , m_eLabelPos( ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS )
163 , m_eTickmarkPos( ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS_AND_AXIS )
164 , m_bCrossingAxisHasReverseDirection(false)
165 , m_bCrossingAxisIsCategoryAxes(false)
166 , m_bDisplayLabels( true )
167 , m_nNumberFormatKey(0)
168 , m_nMajorTickmarks(1)
169 , m_nMinorTickmarks(1)
170 , m_aTickmarkPropertiesList()
171 , m_aLineProperties()
172 //for category axes
173 , m_nAxisType(AxisType::REALNUMBER)
174 , m_bComplexCategories(false)
175 , m_pExplicitCategoriesProvider(pExplicitCategoriesProvider)
176 , m_xAxisTextProvider(0)
180 AxisProperties::AxisProperties( const AxisProperties& rAxisProperties )
181 : m_xAxisModel( rAxisProperties.m_xAxisModel )
182 , m_nDimensionIndex( rAxisProperties.m_nDimensionIndex )
183 , m_bIsMainAxis( rAxisProperties.m_bIsMainAxis )
184 , m_bSwapXAndY( rAxisProperties.m_bSwapXAndY )
185 , m_eCrossoverType( rAxisProperties.m_eCrossoverType )
186 , m_eLabelPos( rAxisProperties.m_eLabelPos )
187 , m_eTickmarkPos( rAxisProperties.m_eTickmarkPos )
188 , m_bCrossingAxisHasReverseDirection( rAxisProperties.m_bCrossingAxisHasReverseDirection )
189 , m_bCrossingAxisIsCategoryAxes( rAxisProperties.m_bCrossingAxisIsCategoryAxes )
190 , maLabelAlignment( rAxisProperties.maLabelAlignment )
191 , m_bDisplayLabels( rAxisProperties.m_bDisplayLabels )
192 , m_nNumberFormatKey( rAxisProperties.m_nNumberFormatKey )
193 , m_nMajorTickmarks( rAxisProperties.m_nMajorTickmarks )
194 , m_nMinorTickmarks( rAxisProperties.m_nMinorTickmarks )
195 , m_aTickmarkPropertiesList( rAxisProperties.m_aTickmarkPropertiesList )
196 , m_aLineProperties( rAxisProperties.m_aLineProperties )
197 //for category axes
198 , m_nAxisType( rAxisProperties.m_nAxisType )
199 , m_bComplexCategories( rAxisProperties.m_bComplexCategories )
200 , m_pExplicitCategoriesProvider( rAxisProperties.m_pExplicitCategoriesProvider )
201 , m_xAxisTextProvider( rAxisProperties.m_xAxisTextProvider )
203 if( rAxisProperties.m_pfMainLinePositionAtOtherAxis )
204 m_pfMainLinePositionAtOtherAxis.reset(*rAxisProperties.m_pfMainLinePositionAtOtherAxis);
205 if( rAxisProperties.m_pfExrtaLinePositionAtOtherAxis )
206 m_pfExrtaLinePositionAtOtherAxis.reset(*rAxisProperties.m_pfExrtaLinePositionAtOtherAxis);
209 LabelAlignment lcl_getLabelAlignmentForZAxis( const AxisProperties& rAxisProperties )
211 LabelAlignment aRet( LABEL_ALIGN_RIGHT );
212 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
213 aRet = LABEL_ALIGN_LEFT;
214 return aRet;
217 LabelAlignment lcl_getLabelAlignmentForYAxis( const AxisProperties& rAxisProperties )
219 LabelAlignment aRet( LABEL_ALIGN_RIGHT );
220 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
221 aRet = LABEL_ALIGN_LEFT;
222 return aRet;
225 LabelAlignment lcl_getLabelAlignmentForXAxis( const AxisProperties& rAxisProperties )
227 LabelAlignment aRet( LABEL_ALIGN_BOTTOM );
228 if (rAxisProperties.maLabelAlignment.mfLabelDirection < 0)
229 aRet = LABEL_ALIGN_TOP;
230 return aRet;
233 void AxisProperties::initAxisPositioning( const uno::Reference< beans::XPropertySet >& xAxisProp )
235 if( !xAxisProp.is() )
236 return;
239 if( AxisHelper::isAxisPositioningEnabled() )
241 xAxisProp->getPropertyValue("CrossoverPosition") >>= m_eCrossoverType;
242 if( ::com::sun::star::chart::ChartAxisPosition_VALUE == m_eCrossoverType )
244 double fValue = 0.0;
245 xAxisProp->getPropertyValue("CrossoverValue") >>= fValue;
247 if( m_bCrossingAxisIsCategoryAxes )
248 fValue = ::rtl::math::round(fValue);
249 m_pfMainLinePositionAtOtherAxis.reset(fValue);
251 else if( ::com::sun::star::chart::ChartAxisPosition_ZERO == m_eCrossoverType )
252 m_pfMainLinePositionAtOtherAxis.reset(0.0);
254 xAxisProp->getPropertyValue("LabelPosition") >>= m_eLabelPos;
255 xAxisProp->getPropertyValue("MarkPosition") >>= m_eTickmarkPos;
257 else
259 m_eCrossoverType = ::com::sun::star::chart::ChartAxisPosition_START;
260 if( m_bIsMainAxis == m_bCrossingAxisHasReverseDirection )
261 m_eCrossoverType = ::com::sun::star::chart::ChartAxisPosition_END;
262 m_eLabelPos = ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS;
263 m_eTickmarkPos = ::com::sun::star::chart::ChartAxisMarkPosition_AT_LABELS;
266 catch( const uno::Exception& e )
268 ASSERT_EXCEPTION( e );
272 void AxisProperties::init( bool bCartesian )
274 uno::Reference< beans::XPropertySet > xProp =
275 uno::Reference<beans::XPropertySet>::query( this->m_xAxisModel );
276 if( !xProp.is() )
277 return;
279 if( m_nDimensionIndex<2 )
280 initAxisPositioning( xProp );
282 ScaleData aScaleData = m_xAxisModel->getScaleData();
283 if( m_nDimensionIndex==0 )
284 AxisHelper::checkDateAxis( aScaleData, m_pExplicitCategoriesProvider, bCartesian );
285 m_nAxisType = aScaleData.AxisType;
287 if( bCartesian )
289 if( m_nDimensionIndex == 0 && m_nAxisType == AxisType::CATEGORY
290 && m_pExplicitCategoriesProvider && m_pExplicitCategoriesProvider->hasComplexCategories() )
291 m_bComplexCategories = true;
293 if( ::com::sun::star::chart::ChartAxisPosition_END == m_eCrossoverType )
294 maLabelAlignment.mfInnerTickDirection = m_bCrossingAxisHasReverseDirection ? 1.0 : -1.0;
295 else
296 maLabelAlignment.mfInnerTickDirection = m_bCrossingAxisHasReverseDirection ? -1.0 : 1.0;
298 if( ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS == m_eLabelPos )
299 maLabelAlignment.mfLabelDirection = maLabelAlignment.mfInnerTickDirection;
300 else if( ::com::sun::star::chart::ChartAxisLabelPosition_NEAR_AXIS_OTHER_SIDE == m_eLabelPos )
301 maLabelAlignment.mfLabelDirection = -maLabelAlignment.mfInnerTickDirection;
302 else if( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START == m_eLabelPos )
303 maLabelAlignment.mfLabelDirection = m_bCrossingAxisHasReverseDirection ? -1 : 1;
304 else if( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END == m_eLabelPos )
305 maLabelAlignment.mfLabelDirection = m_bCrossingAxisHasReverseDirection ? 1 : -1;
307 if( m_nDimensionIndex==2 )
308 maLabelAlignment.meAlignment = lcl_getLabelAlignmentForZAxis(*this);
309 else
311 bool bIsYAxisPosition = (m_nDimensionIndex==1 && !m_bSwapXAndY)
312 || (m_nDimensionIndex==0 && m_bSwapXAndY);
313 if( bIsYAxisPosition )
315 maLabelAlignment.mfLabelDirection *= -1.0;
316 maLabelAlignment.mfInnerTickDirection *= -1.0;
319 if( bIsYAxisPosition )
320 maLabelAlignment.meAlignment = lcl_getLabelAlignmentForYAxis(*this);
321 else
322 maLabelAlignment.meAlignment = lcl_getLabelAlignmentForXAxis(*this);
328 //init LineProperties
329 m_aLineProperties.initFromPropertySet( xProp );
331 //init display labels
332 xProp->getPropertyValue( "DisplayLabels" ) >>= m_bDisplayLabels;
334 //init TickmarkProperties
335 xProp->getPropertyValue( "MajorTickmarks" ) >>= m_nMajorTickmarks;
336 xProp->getPropertyValue( "MinorTickmarks" ) >>= m_nMinorTickmarks;
338 sal_Int32 nMaxDepth = 0;
339 if(m_nMinorTickmarks!=0)
340 nMaxDepth=2;
341 else if(m_nMajorTickmarks!=0)
342 nMaxDepth=1;
344 this->m_aTickmarkPropertiesList.clear();
345 for( sal_Int32 nDepth=0; nDepth<nMaxDepth; nDepth++ )
347 TickmarkProperties aTickmarkProperties = this->makeTickmarkProperties( nDepth );
348 this->m_aTickmarkPropertiesList.push_back( aTickmarkProperties );
351 catch( const uno::Exception& e )
353 ASSERT_EXCEPTION( e );
357 AxisLabelProperties::AxisLabelProperties()
358 : m_aFontReferenceSize( ChartModelHelper::getDefaultPageSize() )
359 , m_aMaximumSpaceForLabels( 0 , 0, m_aFontReferenceSize.Width, m_aFontReferenceSize.Height )
360 , nNumberFormatKey(0)
361 , eStaggering( SIDE_BY_SIDE )
362 , bLineBreakAllowed( false )
363 , bOverlapAllowed( false )
364 , bStackCharacters( false )
365 , fRotationAngleDegree( 0.0 )
366 , nRhythm( 1 )
367 , bRhythmIsFix(false)
372 void AxisLabelProperties::init( const uno::Reference< XAxis >& xAxisModel )
374 uno::Reference< beans::XPropertySet > xProp =
375 uno::Reference<beans::XPropertySet>::query( xAxisModel );
376 if(xProp.is())
380 xProp->getPropertyValue( "TextBreak" ) >>= this->bLineBreakAllowed;
381 xProp->getPropertyValue( "TextOverlap" ) >>= this->bOverlapAllowed;
382 xProp->getPropertyValue( "StackCharacters" ) >>= this->bStackCharacters;
383 xProp->getPropertyValue( "TextRotation" ) >>= this->fRotationAngleDegree;
385 ::com::sun::star::chart::ChartAxisArrangeOrderType eArrangeOrder;
386 xProp->getPropertyValue( "ArrangeOrder" ) >>= eArrangeOrder;
387 switch(eArrangeOrder)
389 case ::com::sun::star::chart::ChartAxisArrangeOrderType_SIDE_BY_SIDE:
390 this->eStaggering = SIDE_BY_SIDE;
391 break;
392 case ::com::sun::star::chart::ChartAxisArrangeOrderType_STAGGER_EVEN:
393 this->eStaggering = STAGGER_EVEN;
394 break;
395 case ::com::sun::star::chart::ChartAxisArrangeOrderType_STAGGER_ODD:
396 this->eStaggering = STAGGER_ODD;
397 break;
398 default:
399 this->eStaggering = STAGGER_AUTO;
400 break;
403 catch( const uno::Exception& e )
405 ASSERT_EXCEPTION( e );
410 bool AxisLabelProperties::isStaggered() const
412 return ( STAGGER_ODD == eStaggering || STAGGER_EVEN == eStaggering );
415 void AxisLabelProperties::autoRotate45()
417 fRotationAngleDegree = 45;
418 bLineBreakAllowed = false;
419 eStaggering = SIDE_BY_SIDE;
422 } //namespace chart
424 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */