merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / view / main / LabelPositionHelper.cxx
blobe9c06ba0c4408b2f74ddcbfc0e93bb4f82756e9f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: LabelPositionHelper.cxx,v $
10 * $Revision: 1.7.44.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "LabelPositionHelper.hxx"
35 #include "PlottingPositionHelper.hxx"
36 #include "CommonConverters.hxx"
37 #include "PropertyMapper.hxx"
38 #include "ShapeFactory.hxx"
39 #include "macros.hxx"
40 #include "RelativeSizeHelper.hxx"
41 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
42 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
44 //.............................................................................
45 namespace chart
47 //.............................................................................
48 using namespace ::com::sun::star;
49 using namespace ::com::sun::star::chart2;
51 LabelPositionHelper::LabelPositionHelper(
52 PlottingPositionHelper* pPosHelper
53 , sal_Int32 nDimensionCount
54 , const uno::Reference< drawing::XShapes >& xLogicTarget
55 , ShapeFactory* pShapeFactory )
56 : m_pPosHelper(pPosHelper)
57 , m_nDimensionCount(nDimensionCount)
58 , m_xLogicTarget(xLogicTarget)
59 , m_pShapeFactory(pShapeFactory)
63 LabelPositionHelper::~LabelPositionHelper()
67 awt::Point LabelPositionHelper::transformSceneToScreenPosition( const drawing::Position3D& rScenePosition3D ) const
69 return PlottingPositionHelper::transformSceneToScreenPosition(
70 rScenePosition3D, m_xLogicTarget, m_pShapeFactory, m_nDimensionCount );
73 //static
74 void LabelPositionHelper::changeTextAdjustment( tAnySequence& rPropValues, const tNameSequence& rPropNames, LabelAlignment eAlignment)
76 //HorizontalAdjustment
78 drawing::TextHorizontalAdjust eHorizontalAdjust = drawing::TextHorizontalAdjust_CENTER;
79 if( LABEL_ALIGN_RIGHT==eAlignment || LABEL_ALIGN_RIGHT_TOP==eAlignment || LABEL_ALIGN_RIGHT_BOTTOM==eAlignment )
80 eHorizontalAdjust = drawing::TextHorizontalAdjust_LEFT;
81 else if( LABEL_ALIGN_LEFT==eAlignment || LABEL_ALIGN_LEFT_TOP==eAlignment || LABEL_ALIGN_LEFT_BOTTOM==eAlignment )
82 eHorizontalAdjust = drawing::TextHorizontalAdjust_RIGHT;
83 uno::Any* pHorizontalAdjustAny = PropertyMapper::getValuePointer(rPropValues,rPropNames,C2U("TextHorizontalAdjust"));
84 if(pHorizontalAdjustAny)
85 *pHorizontalAdjustAny = uno::makeAny(eHorizontalAdjust);
88 //VerticalAdjustment
90 drawing::TextVerticalAdjust eVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
91 if( LABEL_ALIGN_TOP==eAlignment || LABEL_ALIGN_RIGHT_TOP==eAlignment || LABEL_ALIGN_LEFT_TOP==eAlignment )
92 eVerticalAdjust = drawing::TextVerticalAdjust_BOTTOM;
93 else if( LABEL_ALIGN_BOTTOM==eAlignment || LABEL_ALIGN_RIGHT_BOTTOM==eAlignment || LABEL_ALIGN_LEFT_BOTTOM==eAlignment )
94 eVerticalAdjust = drawing::TextVerticalAdjust_TOP;
95 uno::Any* pVerticalAdjustAny = PropertyMapper::getValuePointer(rPropValues,rPropNames,C2U("TextVerticalAdjust"));
96 if(pVerticalAdjustAny)
97 *pVerticalAdjustAny = uno::makeAny(eVerticalAdjust);
101 void lcl_doDynamicFontResize( uno::Any* pAOldAndNewFontHeightAny
102 , const awt::Size& rOldReferenceSize
103 , const awt::Size& rNewReferenceSize )
105 double fOldFontHeight = 0, fNewFontHeight;
106 if( pAOldAndNewFontHeightAny && ( *pAOldAndNewFontHeightAny >>= fOldFontHeight ) )
108 fNewFontHeight = RelativeSizeHelper::calculate( fOldFontHeight, rOldReferenceSize, rNewReferenceSize );
109 *pAOldAndNewFontHeightAny = uno::makeAny(fNewFontHeight);
113 //static
114 void LabelPositionHelper::doDynamicFontResize( tAnySequence& rPropValues
115 , const tNameSequence& rPropNames
116 , const uno::Reference< beans::XPropertySet >& xAxisModelProps
117 , const awt::Size& rNewReferenceSize
120 //-------------------------
121 //handle dynamic font resize:
122 awt::Size aOldReferenceSize;
123 if( xAxisModelProps->getPropertyValue( C2U("ReferencePageSize")) >>= aOldReferenceSize )
125 uno::Any* pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, C2U("CharHeight") );
126 lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
127 pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, C2U("CharHeightAsian") );
128 lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
129 pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, C2U("CharHeightComplex") );
130 lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
134 namespace
137 void lcl_correctRotation_Left( double& rfXCorrection, double& rfYCorrection
138 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
140 //correct label positions for labels on a left side of something with a right centered alignment
141 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
142 if( fAnglePositiveDegree==0.0 )
145 else if( fAnglePositiveDegree<= 90.0 )
147 rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi )/2.0;
148 if( bRotateAroundCenter )
149 rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi )/2.0;
151 else if( fAnglePositiveDegree<= 180.0 )
153 double beta = fAnglePi-F_PI/2.0;
154 rfXCorrection = -aSize.Width *rtl::math::sin( beta )
155 -aSize.Height *rtl::math::cos( beta )/2.0;
156 if( bRotateAroundCenter )
157 rfYCorrection = -aSize.Width *rtl::math::cos( beta )/2.0;
158 else
159 rfYCorrection = -aSize.Width *rtl::math::cos( beta );
161 else if( fAnglePositiveDegree<= 270.0 )
163 double beta = fAnglePi - F_PI;
164 rfXCorrection = -aSize.Width *rtl::math::cos( beta )
165 -aSize.Height*rtl::math::sin( beta )/2.0;
166 if( bRotateAroundCenter )
167 rfYCorrection = aSize.Width *rtl::math::sin( beta )/2.0;
168 else
169 rfYCorrection = aSize.Width *rtl::math::sin( beta );
171 else
173 double beta = 2*F_PI - fAnglePi;
174 rfXCorrection = -aSize.Height*rtl::math::sin( beta )/2.0;
175 if( bRotateAroundCenter )
176 rfYCorrection = aSize.Width*rtl::math::sin( beta )/2.0;
180 void lcl_correctRotation_Right( double& rfXCorrection, double& rfYCorrection
181 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
183 //correct label positions for labels on a right side of something with a left centered alignment
184 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
185 if( fAnglePositiveDegree== 0.0 )
188 else if( fAnglePositiveDegree<= 90.0 )
190 rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi )/2.0;
191 if( bRotateAroundCenter )
192 rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi )/2.0;
194 else if( fAnglePositiveDegree<= 180.0 )
196 double beta = F_PI - fAnglePi;
197 rfXCorrection = aSize.Width *rtl::math::cos( beta )
198 + aSize.Height*rtl::math::sin( beta )/2.0;
199 if( bRotateAroundCenter )
200 rfYCorrection = aSize.Width *rtl::math::sin( beta )/2.0;
201 else
202 rfYCorrection = aSize.Width *rtl::math::sin( beta );
204 else if( fAnglePositiveDegree<= 270.0 )
206 double beta = 3*F_PI/2.0 - fAnglePi;
207 rfXCorrection = aSize.Width *rtl::math::sin( beta )
208 +aSize.Height*rtl::math::cos( beta )/2.0;
209 if( bRotateAroundCenter )
210 rfYCorrection = -aSize.Width *rtl::math::cos( beta )/2.0;
211 else
212 rfYCorrection = -aSize.Width *rtl::math::cos( beta );
214 else
216 rfXCorrection = aSize.Height*rtl::math::sin( 2*F_PI - fAnglePi )/2.0;
217 if( bRotateAroundCenter )
218 rfYCorrection = -aSize.Width*rtl::math::sin( 2*F_PI - fAnglePi )/2.0;
222 void lcl_correctRotation_Top( double& rfXCorrection, double& rfYCorrection
223 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
225 //correct label positions for labels on top of something with a bottom centered alignment
226 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
227 if( fAnglePositiveDegree== 0.0 )
230 else if( fAnglePositiveDegree<= 90.0 )
232 rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi )/2.0;
233 if( !bRotateAroundCenter )
234 rfXCorrection += aSize.Width*rtl::math::cos( fAnglePi )/2.0;
235 rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi )/2.0;
237 else if( fAnglePositiveDegree<= 180.0 )
239 double beta = fAnglePi - F_PI/2.0;
240 rfXCorrection = aSize.Height*rtl::math::cos( beta )/2.0;
241 if( !bRotateAroundCenter )
242 rfXCorrection -= aSize.Width*rtl::math::sin( beta )/2.0;
243 rfYCorrection = -aSize.Width*rtl::math::cos( beta )/2.0
244 - aSize.Height*rtl::math::sin( beta );
246 else if( fAnglePositiveDegree<= 270.0 )
248 double beta = fAnglePi - F_PI;
249 rfXCorrection = -aSize.Height *rtl::math::sin( beta )/2.0;
250 if( !bRotateAroundCenter )
251 rfXCorrection += aSize.Width *rtl::math::cos( beta )/2.0;
252 rfYCorrection = -aSize.Width *rtl::math::sin( beta )/2.0
253 -aSize.Height *rtl::math::cos( beta );
255 else
257 rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi )/2.0;
258 if( !bRotateAroundCenter )
259 rfXCorrection -= aSize.Width*rtl::math::cos( fAnglePi )/2.0;
260 rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi )/2.0;
264 void lcl_correctRotation_Bottom( double& rfXCorrection, double& rfYCorrection
265 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
267 //correct label positions for labels below something with a top centered alignment
268 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
269 if( fAnglePositiveDegree==0.0 )
272 else if( fAnglePositiveDegree<= 90.0 )
274 rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi )/2.0;
275 if( !bRotateAroundCenter )
276 rfXCorrection -= aSize.Width *rtl::math::cos( fAnglePi )/2.0;
277 rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi )/2.0;
279 else if( fAnglePositiveDegree<= 180.0 )
281 double beta = fAnglePi-F_PI/2.0;
282 rfXCorrection = -aSize.Height*rtl::math::cos( beta )/2.0;
283 if( !bRotateAroundCenter )
284 rfXCorrection += aSize.Width *rtl::math::sin( beta )/2.0;
285 rfYCorrection = aSize.Width *rtl::math::cos( beta )/2.0
286 +aSize.Height*rtl::math::sin( beta );
288 else if( fAnglePositiveDegree<= 270.0 )
290 double beta = 3*F_PI/2.0 - fAnglePi;
291 rfXCorrection = aSize.Height*rtl::math::cos( beta )/2.0;
292 if( !bRotateAroundCenter )
293 rfXCorrection -= aSize.Width *rtl::math::sin( beta )/2.0;
294 rfYCorrection = aSize.Height*rtl::math::sin( beta )
295 +aSize.Width*rtl::math::cos( beta )/2.0;
297 else
299 double beta = 2*F_PI - fAnglePi;
300 rfXCorrection = aSize.Height*rtl::math::sin( beta )/2.0;
301 if( !bRotateAroundCenter )
302 rfXCorrection += aSize.Width*rtl::math::cos( beta )/2.0;
303 rfYCorrection = aSize.Width*rtl::math::sin( beta )/2.0;
307 void lcl_correctRotation_Left_Top( double& rfXCorrection, double& rfYCorrection
308 , double fAnglePositiveDegree, const awt::Size& aSize )
310 //correct position for labels at the left top corner of something with a bottom right alignment
311 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
312 if( fAnglePositiveDegree==0.0 )
315 else if( fAnglePositiveDegree<= 90.0 )
317 rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi );
319 else if( fAnglePositiveDegree<= 180.0 )
321 double beta = fAnglePi-F_PI/2.0;
322 rfXCorrection = -aSize.Width*rtl::math::sin( beta );
323 rfYCorrection = -aSize.Height*rtl::math::sin( beta )
324 -aSize.Width*rtl::math::cos( beta );
326 else if( fAnglePositiveDegree<= 270.0 )
328 double beta = 3*F_PI/2.0 - fAnglePi;
329 rfXCorrection = -aSize.Height*rtl::math::cos( beta )
330 -aSize.Width*rtl::math::sin( beta );
331 rfYCorrection = -aSize.Height*rtl::math::sin( beta );
333 else
335 rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi );
339 void lcl_correctRotation_Left_Bottom( double& rfXCorrection, double& rfYCorrection
340 , double fAnglePositiveDegree, const awt::Size& aSize )
342 //correct position for labels at the left bottom corner of something with a top right alignment
343 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
344 if( fAnglePositiveDegree==0.0 )
347 else if( fAnglePositiveDegree<= 90.0 )
349 rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi );
351 else if( fAnglePositiveDegree<= 180.0 )
353 double beta = fAnglePi-F_PI/2.0;
354 rfXCorrection = -aSize.Width*rtl::math::sin( beta )
355 -aSize.Height*rtl::math::cos( beta );;
356 rfYCorrection = aSize.Height*rtl::math::sin( beta );
358 else if( fAnglePositiveDegree<= 270.0 )
360 double beta = 3*F_PI/2.0 - fAnglePi;
361 rfXCorrection = -aSize.Width*rtl::math::sin( beta );
362 rfYCorrection = aSize.Width*rtl::math::cos( beta )
363 +aSize.Height*rtl::math::sin( beta );
365 else
367 rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi );
371 void lcl_correctRotation_Right_Top( double& rfXCorrection, double& rfYCorrection
372 , double fAnglePositiveDegree, const awt::Size& aSize )
374 //correct position for labels at the right top corner of something with a bottom left alignment
375 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
376 if( fAnglePositiveDegree==0.0 )
379 else if( fAnglePositiveDegree<= 90.0 )
381 rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi );
383 else if( fAnglePositiveDegree<= 180.0 )
385 double beta = fAnglePi-F_PI/2.0;
386 rfXCorrection = aSize.Width*rtl::math::sin( beta )
387 +aSize.Height*rtl::math::cos( beta );
388 rfYCorrection = -aSize.Height*rtl::math::sin( beta );
390 else if( fAnglePositiveDegree<= 270.0 )
392 double beta = 3*F_PI/2.0 - fAnglePi;
393 rfXCorrection = aSize.Width*rtl::math::sin( beta );
394 rfYCorrection = -aSize.Width*rtl::math::cos( beta )
395 -aSize.Height*rtl::math::sin( beta );
397 else
399 rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi );
403 void lcl_correctRotation_Right_Bottom( double& rfXCorrection, double& rfYCorrection
404 , double fAnglePositiveDegree, const awt::Size& aSize )
406 //correct position for labels at the right bottom corner of something with a top left alignment
407 double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
408 if( fAnglePositiveDegree==0.0 )
411 else if( fAnglePositiveDegree<= 90.0 )
413 rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi );
415 else if( fAnglePositiveDegree<= 180.0 )
417 double beta = fAnglePi-F_PI/2.0;
418 rfXCorrection = aSize.Width*rtl::math::sin( beta );
419 rfYCorrection = aSize.Height*rtl::math::sin( beta )
420 +aSize.Width*rtl::math::cos( beta );
422 else if( fAnglePositiveDegree<= 270.0 )
424 double beta = 3*F_PI/2.0 - fAnglePi;
425 rfXCorrection = aSize.Height*rtl::math::cos( beta )
426 +aSize.Width*rtl::math::sin( beta );
427 rfYCorrection = aSize.Height*rtl::math::sin( beta );
429 else
431 rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi );
435 }//end anonymous namespace
437 //static
438 void LabelPositionHelper::correctPositionForRotation( const uno::Reference< drawing::XShape >& xShape2DText
439 , LabelAlignment eLabelAlignment, const double fRotationAngle, bool bRotateAroundCenter )
441 if( !xShape2DText.is() )
442 return;
444 awt::Point aOldPos = xShape2DText->getPosition();
445 awt::Size aSize = xShape2DText->getSize();
447 double fYCorrection = 0.0;
448 double fXCorrection = 0.0;
450 double fAnglePositiveDegree = fRotationAngle;
451 while(fAnglePositiveDegree<0.0)
452 fAnglePositiveDegree+=360.0;
454 switch(eLabelAlignment)
456 case LABEL_ALIGN_LEFT:
457 lcl_correctRotation_Left( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
458 break;
459 case LABEL_ALIGN_RIGHT:
460 lcl_correctRotation_Right( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
461 break;
462 case LABEL_ALIGN_TOP:
463 lcl_correctRotation_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
464 break;
465 case LABEL_ALIGN_BOTTOM:
466 lcl_correctRotation_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
467 break;
468 case LABEL_ALIGN_LEFT_TOP:
469 lcl_correctRotation_Left_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
470 break;
471 case LABEL_ALIGN_LEFT_BOTTOM:
472 lcl_correctRotation_Left_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
473 break;
474 case LABEL_ALIGN_RIGHT_TOP:
475 lcl_correctRotation_Right_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
476 break;
477 case LABEL_ALIGN_RIGHT_BOTTOM:
478 lcl_correctRotation_Right_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
479 break;
480 default: //LABEL_ALIGN_CENTER
481 break;
484 xShape2DText->setPosition( awt::Point(
485 static_cast<sal_Int32>(aOldPos.X + fXCorrection )
486 , static_cast<sal_Int32>(aOldPos.Y + fYCorrection ) ) );
489 //.............................................................................
490 } //namespace chart
491 //.............................................................................