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 "Tickmarks.hxx"
21 : : #include "Tickmarks_Equidistant.hxx"
22 : : #include "Tickmarks_Dates.hxx"
23 : : #include "ViewDefines.hxx"
24 : : #include <rtl/math.hxx>
25 : : #include <memory>
26 : :
27 : : //.............................................................................
28 : : namespace chart
29 : : {
30 : : //.............................................................................
31 : : using namespace ::com::sun::star;
32 : : using namespace ::com::sun::star::chart2;
33 : : using namespace ::rtl::math;
34 : : using ::basegfx::B2DVector;
35 : :
36 : 72875 : TickInfo::TickInfo( const ::com::sun::star::uno::Reference<
37 : : ::com::sun::star::chart2::XScaling >& xInverse )
38 : : : fScaledTickValue( 0.0 )
39 : : , xInverseScaling( xInverse )
40 : : , aTickScreenPosition(0.0,0.0)
41 : : , bPaintIt( true )
42 : : , xTextShape( NULL )
43 [ + - ]: 72875 : , nFactorForLimitedTextWidth(1)
44 : : {
45 : 72875 : }
46 : :
47 : 16009 : double TickInfo::getUnscaledTickValue() const
48 : : {
49 [ + + ]: 16009 : if( xInverseScaling.is() )
50 : 7688 : return xInverseScaling->doScaling( fScaledTickValue );
51 : : else
52 : 16009 : return fScaledTickValue;
53 : : }
54 : :
55 : 1680 : sal_Int32 TickInfo::getScreenDistanceBetweenTicks( const TickInfo& rOherTickInfo ) const
56 : : {
57 : : //return the positive distance between the two first tickmarks in screen values
58 : :
59 : 1680 : B2DVector aDistance = rOherTickInfo.aTickScreenPosition - aTickScreenPosition;
60 [ + - ]: 1680 : sal_Int32 nRet = static_cast<sal_Int32>(aDistance.getLength());
61 [ - + ]: 1680 : if(nRet<0)
62 : 0 : nRet *= -1;
63 : 1680 : return nRet;
64 : : }
65 : :
66 : 3465 : PureTickIter::PureTickIter( ::std::vector< TickInfo >& rTickInfoVector )
67 : : : m_rTickVector(rTickInfoVector)
68 : 3465 : , m_aTickIter(m_rTickVector.begin())
69 : : {
70 : 3465 : }
71 : 3465 : PureTickIter::~PureTickIter()
72 : : {
73 [ - + ]: 5146 : }
74 : 5259 : TickInfo* PureTickIter::firstInfo()
75 : : {
76 : 5259 : m_aTickIter = m_rTickVector.begin();
77 [ + - ][ + - ]: 5259 : if(m_aTickIter!=m_rTickVector.end())
78 : 5259 : return &*m_aTickIter;
79 : 5259 : return 0;
80 : : }
81 : 20476 : TickInfo* PureTickIter::nextInfo()
82 : : {
83 [ + - ][ + + ]: 20476 : if(m_aTickIter!=m_rTickVector.end())
84 : : {
85 : 19587 : ++m_aTickIter;
86 [ + + ][ + - ]: 19587 : if(m_aTickIter!=m_rTickVector.end())
87 : 16107 : return &*m_aTickIter;
88 : : }
89 : 20476 : return 0;
90 : : }
91 : :
92 : : //-----------------------------------------------------------------------------
93 : : //-----------------------------------------------------------------------------
94 : : //-----------------------------------------------------------------------------
95 : :
96 : 12536 : TickFactory::TickFactory(
97 : : const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement )
98 : : : m_rScale( rScale )
99 : : , m_rIncrement( rIncrement )
100 [ + - ][ + - ]: 12536 : , m_xInverseScaling(NULL)
101 : : {
102 : : //@todo: make sure that the scale is valid for the scaling
103 : :
104 [ + + ]: 12536 : if( m_rScale.Scaling.is() )
105 : : {
106 [ + - ][ + - ]: 5538 : m_xInverseScaling = m_rScale.Scaling->getInverseScaling();
[ + - ]
107 : : OSL_ENSURE( m_xInverseScaling.is(), "each Scaling needs to return a inverse Scaling" );
108 : : }
109 : :
110 : 12536 : m_fScaledVisibleMin = m_rScale.Minimum;
111 [ + + ]: 12536 : if( m_xInverseScaling.is() )
112 [ + - ][ + - ]: 5538 : m_fScaledVisibleMin = m_rScale.Scaling->doScaling(m_fScaledVisibleMin);
113 : :
114 : 12536 : m_fScaledVisibleMax = m_rScale.Maximum;
115 [ + + ]: 12536 : if( m_xInverseScaling.is() )
116 [ + - ][ + - ]: 5538 : m_fScaledVisibleMax = m_rScale.Scaling->doScaling(m_fScaledVisibleMax);
117 : 12536 : }
118 : :
119 : 12536 : TickFactory::~TickFactory()
120 : : {
121 [ - + ]: 14474 : }
122 : :
123 : 6465 : bool TickFactory::isDateAxis() const
124 : : {
125 : 6465 : return m_rScale.AxisType == AxisType::DATE;
126 : : }
127 : :
128 : 4657 : void TickFactory::getAllTicks( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
129 : : {
130 [ - + ]: 4657 : if( isDateAxis() )
131 [ # # ]: 0 : DateTickFactory( m_rScale, m_rIncrement ).getAllTicks( rAllTickInfos );
132 : : else
133 [ + - ]: 4657 : EquidistantTickFactory( m_rScale, m_rIncrement ).getAllTicks( rAllTickInfos );
134 : 4657 : }
135 : :
136 : 1808 : void TickFactory::getAllTicksShifted( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
137 : : {
138 [ - + ]: 1808 : if( isDateAxis() )
139 [ # # ]: 0 : DateTickFactory( m_rScale, m_rIncrement ).getAllTicksShifted( rAllTickInfos );
140 : : else
141 [ + - ]: 1808 : EquidistantTickFactory( m_rScale, m_rIncrement ).getAllTicksShifted( rAllTickInfos );
142 : 1808 : }
143 : :
144 : : //-----------------------------------------------------------------------------
145 : : // ___TickFactory_2D___
146 : : //-----------------------------------------------------------------------------
147 : 10598 : TickFactory_2D::TickFactory_2D(
148 : : const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement
149 : : //, double fStrech_SceneToScreen, double fOffset_SceneToScreen )
150 : : , const B2DVector& rStartScreenPos, const B2DVector& rEndScreenPos
151 : : , const B2DVector& rAxisLineToLabelLineShift )
152 : : : TickFactory( rScale, rIncrement )
153 : : , m_aAxisStartScreenPosition2D(rStartScreenPos)
154 : : , m_aAxisEndScreenPosition2D(rEndScreenPos)
155 : : , m_aAxisLineToLabelLineShift(rAxisLineToLabelLineShift)
156 : : , m_fStrech_LogicToScreen(1.0)
157 : 10598 : , m_fOffset_LogicToScreen(0.0)
158 : : {
159 : 10598 : double fWidthY = m_fScaledVisibleMax - m_fScaledVisibleMin;
160 [ + + ]: 10598 : if( AxisOrientation_MATHEMATICAL==m_rScale.Orientation )
161 : : {
162 : 10511 : m_fStrech_LogicToScreen = 1.0/fWidthY;
163 : 10511 : m_fOffset_LogicToScreen = -m_fScaledVisibleMin;
164 : : }
165 : : else
166 : : {
167 : 87 : B2DVector aSwap(m_aAxisStartScreenPosition2D);
168 [ + - ]: 87 : m_aAxisStartScreenPosition2D = m_aAxisEndScreenPosition2D;
169 [ + - ]: 87 : m_aAxisEndScreenPosition2D = aSwap;
170 : :
171 : 87 : m_fStrech_LogicToScreen = -1.0/fWidthY;
172 : 87 : m_fOffset_LogicToScreen = -m_fScaledVisibleMax;
173 : : }
174 : 10598 : }
175 : :
176 : 10598 : TickFactory_2D::~TickFactory_2D()
177 : : {
178 [ - + ]: 21196 : }
179 : :
180 : 5101 : bool TickFactory_2D::isHorizontalAxis() const
181 : : {
182 : 5101 : return ( m_aAxisStartScreenPosition2D.getY() == m_aAxisEndScreenPosition2D.getY() );
183 : : }
184 : 5101 : bool TickFactory_2D::isVerticalAxis() const
185 : : {
186 : 5101 : return ( m_aAxisStartScreenPosition2D.getX() == m_aAxisEndScreenPosition2D.getX() );
187 : : }
188 : :
189 : : //static
190 : 1681 : sal_Int32 TickFactory_2D::getTickScreenDistance( TickIter& rIter )
191 : : {
192 : : //return the positive distance between the two first tickmarks in screen values
193 : : //if there are less than two tickmarks -1 is returned
194 : :
195 : 1681 : const TickInfo* pFirstTickInfo = rIter.firstInfo();
196 : 1681 : const TickInfo* pSecondTickInfo = rIter.nextInfo();
197 [ - + ][ + + ]: 1681 : if(!pSecondTickInfo || !pFirstTickInfo)
198 : 1 : return -1;
199 : :
200 : 1681 : return pFirstTickInfo->getScreenDistanceBetweenTicks( *pSecondTickInfo );
201 : : }
202 : :
203 : 88782 : B2DVector TickFactory_2D::getTickScreenPosition2D( double fScaledLogicTickValue ) const
204 : : {
205 : 88782 : B2DVector aRet(m_aAxisStartScreenPosition2D);
206 : : aRet += (m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D)
207 : 88782 : *((fScaledLogicTickValue+m_fOffset_LogicToScreen)*m_fStrech_LogicToScreen);
208 : 88782 : return aRet;
209 : : }
210 : :
211 : 22204 : void TickFactory_2D::addPointSequenceForTickLine( drawing::PointSequenceSequence& rPoints
212 : : , sal_Int32 nSequenceIndex
213 : : , double fScaledLogicTickValue, double fInnerDirectionSign
214 : : , const TickmarkProperties& rTickmarkProperties
215 : : , bool bPlaceAtLabels ) const
216 : : {
217 [ - + ]: 22204 : if( fInnerDirectionSign==0.0 )
218 : 0 : fInnerDirectionSign = 1.0;
219 : :
220 : 22204 : B2DVector aTickScreenPosition = this->getTickScreenPosition2D(fScaledLogicTickValue);
221 [ + + ]: 22204 : if( bPlaceAtLabels )
222 : 11421 : aTickScreenPosition += m_aAxisLineToLabelLineShift;
223 : :
224 : 22204 : B2DVector aMainDirection = m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D;
225 [ + - ]: 22204 : aMainDirection.normalize();
226 : 22204 : B2DVector aOrthoDirection(-aMainDirection.getY(),aMainDirection.getX());
227 : 22204 : aOrthoDirection *= fInnerDirectionSign;
228 [ + - ]: 22204 : aOrthoDirection.normalize();
229 : :
230 : 22204 : B2DVector aStart = aTickScreenPosition + aOrthoDirection*rTickmarkProperties.RelativePos;
231 : 22204 : B2DVector aEnd = aStart - aOrthoDirection*rTickmarkProperties.Length;
232 : :
233 [ + - ][ + - ]: 22204 : rPoints[nSequenceIndex].realloc(2);
234 [ + - ][ + - ]: 22204 : rPoints[nSequenceIndex][0].X = static_cast<sal_Int32>(aStart.getX());
235 [ + - ][ + - ]: 22204 : rPoints[nSequenceIndex][0].Y = static_cast<sal_Int32>(aStart.getY());
236 [ + - ][ + - ]: 22204 : rPoints[nSequenceIndex][1].X = static_cast<sal_Int32>(aEnd.getX());
237 [ + - ][ + - ]: 22204 : rPoints[nSequenceIndex][1].Y = static_cast<sal_Int32>(aEnd.getY());
238 : 22204 : }
239 : :
240 : 13570 : B2DVector TickFactory_2D::getDistanceAxisTickToText( const AxisProperties& rAxisProperties, bool bIncludeFarAwayDistanceIfSo, bool bIncludeSpaceBetweenTickAndText ) const
241 : : {
242 : 13570 : bool bFarAwayLabels = false;
243 [ + + ][ - + ]: 13570 : if( ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_START == rAxisProperties.m_eLabelPos
244 : : || ::com::sun::star::chart::ChartAxisLabelPosition_OUTSIDE_END == rAxisProperties.m_eLabelPos )
245 : 600 : bFarAwayLabels = true;
246 : :
247 : 13570 : double fInnerDirectionSign = rAxisProperties.m_fInnerDirectionSign;
248 [ - + ]: 13570 : if( fInnerDirectionSign==0.0 )
249 : 0 : fInnerDirectionSign = 1.0;
250 : :
251 : 13570 : B2DVector aMainDirection = m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D;
252 [ + - ]: 13570 : aMainDirection.normalize();
253 : 13570 : B2DVector aOrthoDirection(-aMainDirection.getY(),aMainDirection.getX());
254 : 13570 : aOrthoDirection *= fInnerDirectionSign;
255 [ + - ]: 13570 : aOrthoDirection.normalize();
256 : :
257 : 13570 : B2DVector aStart(0,0), aEnd(0,0);
258 [ + + ]: 13570 : if( bFarAwayLabels )
259 : : {
260 [ + - ]: 600 : TickmarkProperties aProps( AxisProperties::getBiggestTickmarkProperties() );
261 [ + - ]: 600 : aStart = aOrthoDirection*aProps.RelativePos;
262 [ + - ]: 600 : aEnd = aStart - aOrthoDirection*aProps.Length;
263 : : }
264 : : else
265 : : {
266 [ + + ]: 26120 : for( sal_Int32 nN=rAxisProperties.m_aTickmarkPropertiesList.size();nN--;)
267 : : {
268 : 13150 : const TickmarkProperties& rProps = rAxisProperties.m_aTickmarkPropertiesList[nN];
269 : 13150 : B2DVector aNewStart = aOrthoDirection*rProps.RelativePos;
270 : 13150 : B2DVector aNewEnd = aNewStart - aOrthoDirection*rProps.Length;
271 [ + - ][ + - ]: 13150 : if(aNewStart.getLength()>aStart.getLength())
[ + - ]
272 [ + - ]: 13150 : aStart=aNewStart;
273 [ + - ][ + - ]: 13150 : if(aNewEnd.getLength()>aEnd.getLength())
[ + + ]
274 [ + - ]: 360 : aEnd=aNewEnd;
275 : 13150 : }
276 : : }
277 : :
278 : 13570 : B2DVector aLabelDirection(aStart);
279 [ + + ]: 13570 : if( rAxisProperties.m_fInnerDirectionSign != rAxisProperties.m_fLabelDirectionSign )
280 [ + - ]: 127 : aLabelDirection = aEnd;
281 : :
282 : 13570 : B2DVector aOrthoLabelDirection(aOrthoDirection);
283 [ + + ]: 13570 : if( rAxisProperties.m_fInnerDirectionSign != rAxisProperties.m_fLabelDirectionSign )
284 : 127 : aOrthoLabelDirection*=-1.0;
285 [ + - ]: 13570 : aOrthoLabelDirection.normalize();
286 [ + - ]: 13570 : if( bIncludeSpaceBetweenTickAndText )
287 : 13570 : aLabelDirection += aOrthoLabelDirection*AXIS2D_TICKLABELSPACING;
288 [ + + ][ + - ]: 13570 : if( bFarAwayLabels && bIncludeFarAwayDistanceIfSo )
289 : 600 : aLabelDirection += m_aAxisLineToLabelLineShift;
290 : 13570 : return aLabelDirection;
291 : : }
292 : :
293 : 1778 : void TickFactory_2D::createPointSequenceForAxisMainLine( drawing::PointSequenceSequence& rPoints ) const
294 : : {
295 : 1778 : rPoints[0].realloc(2);
296 : 1778 : rPoints[0][0].X = static_cast<sal_Int32>(m_aAxisStartScreenPosition2D.getX());
297 : 1778 : rPoints[0][0].Y = static_cast<sal_Int32>(m_aAxisStartScreenPosition2D.getY());
298 : 1778 : rPoints[0][1].X = static_cast<sal_Int32>(m_aAxisEndScreenPosition2D.getX());
299 : 1778 : rPoints[0][1].Y = static_cast<sal_Int32>(m_aAxisEndScreenPosition2D.getY());
300 : 1778 : }
301 : :
302 : 6025 : void TickFactory_2D::updateScreenValues( ::std::vector< ::std::vector< TickInfo > >& rAllTickInfos ) const
303 : : {
304 : : //get the transformed screen values for all tickmarks in rAllTickInfos
305 : 6025 : ::std::vector< ::std::vector< TickInfo > >::iterator aDepthIter = rAllTickInfos.begin();
306 [ + - ]: 6025 : const ::std::vector< ::std::vector< TickInfo > >::const_iterator aDepthEnd = rAllTickInfos.end();
307 [ + - ][ + + ]: 17885 : for( ; aDepthIter != aDepthEnd; ++aDepthIter )
308 : : {
309 : 11860 : ::std::vector< TickInfo >::iterator aTickIter = (*aDepthIter).begin();
310 [ + - ]: 11860 : const ::std::vector< TickInfo >::const_iterator aTickEnd = (*aDepthIter).end();
311 [ + - ][ + + ]: 78438 : for( ; aTickIter != aTickEnd; ++aTickIter )
312 : : {
313 : 66578 : TickInfo& rTickInfo = (*aTickIter);
314 : : rTickInfo.aTickScreenPosition =
315 [ + - ]: 66578 : this->getTickScreenPosition2D( rTickInfo.fScaledTickValue );
316 : : }
317 : : }
318 : 6025 : }
319 : :
320 : : //.............................................................................
321 : : } //namespace chart
322 : : //.............................................................................
323 : :
324 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|