tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / chart2 / source / view / main / LabelPositionHelper.cxx
blob4b3079ce722518d17b63e864c97be480dda1fa98
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 <LabelPositionHelper.hxx>
21 #include <PlottingPositionHelper.hxx>
22 #include <PropertyMapper.hxx>
23 #include <RelativeSizeHelper.hxx>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
26 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
28 #include <cmath>
29 #include <utility>
31 namespace chart
33 using namespace ::com::sun::star;
35 LabelPositionHelper::LabelPositionHelper(
36 sal_Int32 nDimensionCount
37 , rtl::Reference<SvxShapeGroupAnyD> xLogicTarget)
38 : m_nDimensionCount(nDimensionCount)
39 , m_xLogicTarget(std::move(xLogicTarget))
43 LabelPositionHelper::~LabelPositionHelper()
47 awt::Point LabelPositionHelper::transformSceneToScreenPosition( const drawing::Position3D& rScenePosition3D ) const
49 return PlottingPositionHelper::transformSceneToScreenPosition(
50 rScenePosition3D, m_xLogicTarget, m_nDimensionCount );
53 void LabelPositionHelper::changeTextAdjustment( tAnySequence& rPropValues, const tNameSequence& rPropNames, LabelAlignment eAlignment)
55 uno::Any* pHorizontalAdjustAny
56 = PropertyMapper::getValuePointer(rPropValues, rPropNames, u"TextHorizontalAdjust");
57 if (pHorizontalAdjustAny)
59 drawing::TextHorizontalAdjust eHorizontalAdjust = drawing::TextHorizontalAdjust_CENTER;
60 if( eAlignment==LABEL_ALIGN_RIGHT || eAlignment==LABEL_ALIGN_RIGHT_TOP || eAlignment==LABEL_ALIGN_RIGHT_BOTTOM )
61 eHorizontalAdjust = drawing::TextHorizontalAdjust_LEFT;
62 else if( eAlignment==LABEL_ALIGN_LEFT || eAlignment==LABEL_ALIGN_LEFT_TOP || eAlignment==LABEL_ALIGN_LEFT_BOTTOM )
63 eHorizontalAdjust = drawing::TextHorizontalAdjust_RIGHT;
64 *pHorizontalAdjustAny <<= eHorizontalAdjust;
67 uno::Any* pVerticalAdjustAny
68 = PropertyMapper::getValuePointer(rPropValues, rPropNames, u"TextVerticalAdjust");
69 if (pVerticalAdjustAny)
71 drawing::TextVerticalAdjust eVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
72 if( eAlignment==LABEL_ALIGN_TOP || eAlignment==LABEL_ALIGN_RIGHT_TOP || eAlignment==LABEL_ALIGN_LEFT_TOP )
73 eVerticalAdjust = drawing::TextVerticalAdjust_BOTTOM;
74 else if( eAlignment==LABEL_ALIGN_BOTTOM || eAlignment==LABEL_ALIGN_RIGHT_BOTTOM || eAlignment==LABEL_ALIGN_LEFT_BOTTOM )
75 eVerticalAdjust = drawing::TextVerticalAdjust_TOP;
76 *pVerticalAdjustAny <<= eVerticalAdjust;
80 static void lcl_doDynamicFontResize( uno::Any* pAOldAndNewFontHeightAny
81 , const awt::Size& rOldReferenceSize
82 , const awt::Size& rNewReferenceSize )
84 double fOldFontHeight = 0;
85 if( pAOldAndNewFontHeightAny && ( *pAOldAndNewFontHeightAny >>= fOldFontHeight ) )
87 double fNewFontHeight = RelativeSizeHelper::calculate( fOldFontHeight, rOldReferenceSize, rNewReferenceSize );
88 *pAOldAndNewFontHeightAny <<= fNewFontHeight;
92 void LabelPositionHelper::doDynamicFontResize( tAnySequence& rPropValues
93 , const tNameSequence& rPropNames
94 , const uno::Reference< beans::XPropertySet >& xAxisModelProps
95 , const awt::Size& rNewReferenceSize
98 //handle dynamic font resize:
99 awt::Size aOldReferenceSize;
100 if( xAxisModelProps->getPropertyValue( u"ReferencePageSize"_ustr) >>= aOldReferenceSize )
102 uno::Any* pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, u"CharHeight" );
103 lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
104 pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, u"CharHeightAsian" );
105 lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
106 pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, u"CharHeightComplex" );
107 lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
111 namespace
114 void lcl_correctRotation_Left( double& rfXCorrection, double& rfYCorrection
115 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
117 //correct label positions for labels on a left side of something with a right centered alignment
118 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
119 if( fAnglePositiveDegree==0.0 )
122 else if( fAnglePositiveDegree<= 90.0 )
124 rfXCorrection = -aSize.Height*std::sin( fAnglePi )/2.0;
125 if( bRotateAroundCenter )
126 rfYCorrection = -aSize.Width*std::sin( fAnglePi )/2.0;
128 else if( fAnglePositiveDegree<= 180.0 )
130 double beta = fAnglePi-M_PI_2;
131 rfXCorrection = -aSize.Width *std::sin( beta )
132 -aSize.Height *std::cos( beta )/2.0;
133 if( bRotateAroundCenter )
134 rfYCorrection = -aSize.Width *std::cos( beta )/2.0;
135 else
136 rfYCorrection = -aSize.Width *std::cos( beta );
138 else if( fAnglePositiveDegree<= 270.0 )
140 double beta = fAnglePi - M_PI;
141 rfXCorrection = -aSize.Width *std::cos( beta )
142 -aSize.Height*std::sin( beta )/2.0;
143 if( bRotateAroundCenter )
144 rfYCorrection = aSize.Width *std::sin( beta )/2.0;
145 else
146 rfYCorrection = aSize.Width *std::sin( beta );
148 else
150 double beta = 2*M_PI - fAnglePi;
151 rfXCorrection = -aSize.Height*std::sin( beta )/2.0;
152 if( bRotateAroundCenter )
153 rfYCorrection = aSize.Width*std::sin( beta )/2.0;
157 void lcl_correctRotation_Right( double& rfXCorrection, double& rfYCorrection
158 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
160 //correct label positions for labels on a right side of something with a left centered alignment
161 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
162 if( fAnglePositiveDegree== 0.0 )
165 else if( fAnglePositiveDegree<= 90.0 )
167 rfXCorrection = aSize.Height*std::sin( fAnglePi )/2.0;
168 if( bRotateAroundCenter )
169 rfYCorrection = aSize.Width*std::sin( fAnglePi )/2.0;
171 else if( fAnglePositiveDegree<= 180.0 )
173 double beta = M_PI - fAnglePi;
174 rfXCorrection = aSize.Width *std::cos( beta )
175 + aSize.Height*std::sin( beta )/2.0;
176 if( bRotateAroundCenter )
177 rfYCorrection = aSize.Width *std::sin( beta )/2.0;
178 else
179 rfYCorrection = aSize.Width *std::sin( beta );
181 else if( fAnglePositiveDegree<= 270.0 )
183 double beta = 3*M_PI_2 - fAnglePi;
184 rfXCorrection = aSize.Width *std::sin( beta )
185 +aSize.Height*std::cos( beta )/2.0;
186 if( bRotateAroundCenter )
187 rfYCorrection = -aSize.Width *std::cos( beta )/2.0;
188 else
189 rfYCorrection = -aSize.Width *std::cos( beta );
191 else
193 rfXCorrection = aSize.Height*std::sin( 2*M_PI - fAnglePi )/2.0;
194 if( bRotateAroundCenter )
195 rfYCorrection = -aSize.Width*std::sin( 2*M_PI - fAnglePi )/2.0;
199 void lcl_correctRotation_Top( double& rfXCorrection, double& rfYCorrection
200 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
202 //correct label positions for labels on top of something with a bottom centered alignment
203 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
204 if( fAnglePositiveDegree== 0.0 )
207 else if( fAnglePositiveDegree<= 90.0 )
209 rfXCorrection = aSize.Height*std::sin( fAnglePi )/2.0;
210 if( !bRotateAroundCenter )
211 rfXCorrection += aSize.Width*std::cos( fAnglePi )/2.0;
212 rfYCorrection = -aSize.Width*std::sin( fAnglePi )/2.0;
214 else if( fAnglePositiveDegree<= 180.0 )
216 double beta = fAnglePi - M_PI_2;
217 rfXCorrection = aSize.Height*std::cos( beta )/2.0;
218 if( !bRotateAroundCenter )
219 rfXCorrection -= aSize.Width*std::sin( beta )/2.0;
220 rfYCorrection = -aSize.Width*std::cos( beta )/2.0
221 - aSize.Height*std::sin( beta );
223 else if( fAnglePositiveDegree<= 270.0 )
225 double beta = fAnglePi - M_PI;
226 rfXCorrection = -aSize.Height *std::sin( beta )/2.0;
227 if( !bRotateAroundCenter )
228 rfXCorrection += aSize.Width *std::cos( beta )/2.0;
229 rfYCorrection = -aSize.Width *std::sin( beta )/2.0
230 -aSize.Height *std::cos( beta );
232 else
234 rfXCorrection = aSize.Height*std::sin( fAnglePi )/2.0;
235 if( !bRotateAroundCenter )
236 rfXCorrection -= aSize.Width*std::cos( fAnglePi )/2.0;
237 rfYCorrection = aSize.Width*std::sin( fAnglePi )/2.0;
241 void lcl_correctRotation_Bottom( double& rfXCorrection, double& rfYCorrection
242 , double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
244 //correct label positions for labels below something with a top centered alignment
245 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
246 if( fAnglePositiveDegree==0.0 )
249 else if( fAnglePositiveDegree<= 90.0 )
251 rfXCorrection = -aSize.Height*std::sin( fAnglePi )/2.0;
252 if( !bRotateAroundCenter )
253 rfXCorrection -= aSize.Width *std::cos( fAnglePi )/2.0;
254 rfYCorrection = aSize.Width*std::sin( fAnglePi )/2.0;
256 else if( fAnglePositiveDegree<= 180.0 )
258 double beta = fAnglePi-M_PI_2;
259 rfXCorrection = -aSize.Height*std::cos( beta )/2.0;
260 if( !bRotateAroundCenter )
261 rfXCorrection += aSize.Width *std::sin( beta )/2.0;
262 rfYCorrection = aSize.Width *std::cos( beta )/2.0
263 +aSize.Height*std::sin( beta );
265 else if( fAnglePositiveDegree<= 270.0 )
267 double beta = 3*M_PI_2 - fAnglePi;
268 rfXCorrection = aSize.Height*std::cos( beta )/2.0;
269 if( !bRotateAroundCenter )
270 rfXCorrection -= aSize.Width *std::sin( beta )/2.0;
271 rfYCorrection = aSize.Height*std::sin( beta )
272 +aSize.Width*std::cos( beta )/2.0;
274 else
276 double beta = 2*M_PI - fAnglePi;
277 rfXCorrection = aSize.Height*std::sin( beta )/2.0;
278 if( !bRotateAroundCenter )
279 rfXCorrection += aSize.Width*std::cos( beta )/2.0;
280 rfYCorrection = aSize.Width*std::sin( beta )/2.0;
284 void lcl_correctRotation_Left_Top( double& rfXCorrection, double& rfYCorrection
285 , double fAnglePositiveDegree, const awt::Size& aSize )
287 //correct position for labels at the left top corner of something with a bottom right alignment
288 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
289 if( fAnglePositiveDegree==0.0 )
292 else if( fAnglePositiveDegree<= 90.0 )
294 rfYCorrection = -aSize.Width*std::sin( fAnglePi );
296 else if( fAnglePositiveDegree<= 180.0 )
298 double beta = fAnglePi-M_PI_2;
299 rfXCorrection = -aSize.Width*std::sin( beta );
300 rfYCorrection = -aSize.Height*std::sin( beta )
301 -aSize.Width*std::cos( beta );
303 else if( fAnglePositiveDegree<= 270.0 )
305 double beta = 3*M_PI_2 - fAnglePi;
306 rfXCorrection = -aSize.Height*std::cos( beta )
307 -aSize.Width*std::sin( beta );
308 rfYCorrection = -aSize.Height*std::sin( beta );
310 else
312 rfXCorrection = aSize.Height*std::sin( fAnglePi );
316 void lcl_correctRotation_Left_Bottom( double& rfXCorrection, double& rfYCorrection
317 , double fAnglePositiveDegree, const awt::Size& aSize )
319 //correct position for labels at the left bottom corner of something with a top right alignment
320 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
321 if( fAnglePositiveDegree==0.0 )
324 else if( fAnglePositiveDegree<= 90.0 )
326 rfXCorrection = -aSize.Height*std::sin( fAnglePi );
328 else if( fAnglePositiveDegree<= 180.0 )
330 double beta = fAnglePi-M_PI_2;
331 rfXCorrection = -aSize.Width*std::sin( beta )
332 -aSize.Height*std::cos( beta );
333 rfYCorrection = aSize.Height*std::sin( beta );
335 else if( fAnglePositiveDegree<= 270.0 )
337 double beta = 3*M_PI_2 - fAnglePi;
338 rfXCorrection = -aSize.Width*std::sin( beta );
339 rfYCorrection = aSize.Width*std::cos( beta )
340 +aSize.Height*std::sin( beta );
342 else
344 rfYCorrection = -aSize.Width*std::sin( fAnglePi );
348 void lcl_correctRotation_Right_Top( double& rfXCorrection, double& rfYCorrection
349 , double fAnglePositiveDegree, const awt::Size& aSize )
351 //correct position for labels at the right top corner of something with a bottom left alignment
352 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
353 if( fAnglePositiveDegree==0.0 )
356 else if( fAnglePositiveDegree<= 90.0 )
358 rfXCorrection = aSize.Height*std::sin( fAnglePi );
360 else if( fAnglePositiveDegree<= 180.0 )
362 double beta = fAnglePi-M_PI_2;
363 rfXCorrection = aSize.Width*std::sin( beta )
364 +aSize.Height*std::cos( beta );
365 rfYCorrection = -aSize.Height*std::sin( beta );
367 else if( fAnglePositiveDegree<= 270.0 )
369 double beta = 3*M_PI_2 - fAnglePi;
370 rfXCorrection = aSize.Width*std::sin( beta );
371 rfYCorrection = -aSize.Width*std::cos( beta )
372 -aSize.Height*std::sin( beta );
374 else
376 rfYCorrection = aSize.Width*std::sin( fAnglePi );
380 void lcl_correctRotation_Right_Bottom( double& rfXCorrection, double& rfYCorrection
381 , double fAnglePositiveDegree, const awt::Size& aSize )
383 //correct position for labels at the right bottom corner of something with a top left alignment
384 double fAnglePi = basegfx::deg2rad(fAnglePositiveDegree);
385 if( fAnglePositiveDegree==0.0 )
388 else if( fAnglePositiveDegree<= 90.0 )
390 rfYCorrection = aSize.Width*std::sin( fAnglePi );
392 else if( fAnglePositiveDegree<= 180.0 )
394 double beta = fAnglePi-M_PI_2;
395 rfXCorrection = aSize.Width*std::sin( beta );
396 rfYCorrection = aSize.Height*std::sin( beta )
397 +aSize.Width*std::cos( beta );
399 else if( fAnglePositiveDegree<= 270.0 )
401 double beta = 3*M_PI_2 - fAnglePi;
402 rfXCorrection = aSize.Height*std::cos( beta )
403 +aSize.Width*std::sin( beta );
404 rfYCorrection = aSize.Height*std::sin( beta );
406 else
408 rfXCorrection = -aSize.Height*std::sin( fAnglePi );
412 }//end anonymous namespace
414 void LabelPositionHelper::correctPositionForRotation( const rtl::Reference<SvxShapeText>& xShape2DText
415 , LabelAlignment eLabelAlignment, const double fRotationAngle, bool bRotateAroundCenter )
417 if( !xShape2DText.is() )
418 return;
420 awt::Point aOldPos = xShape2DText->getPosition();
421 awt::Size aSize = xShape2DText->getSize();
423 double fYCorrection = 0.0;
424 double fXCorrection = 0.0;
426 double fAnglePositiveDegree = fRotationAngle;
427 while(fAnglePositiveDegree<0.0)
428 fAnglePositiveDegree+=360.0;
430 switch(eLabelAlignment)
432 case LABEL_ALIGN_LEFT:
433 lcl_correctRotation_Left( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
434 break;
435 case LABEL_ALIGN_RIGHT:
436 lcl_correctRotation_Right( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
437 break;
438 case LABEL_ALIGN_TOP:
439 lcl_correctRotation_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
440 break;
441 case LABEL_ALIGN_BOTTOM:
442 lcl_correctRotation_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
443 break;
444 case LABEL_ALIGN_LEFT_TOP:
445 lcl_correctRotation_Left_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
446 break;
447 case LABEL_ALIGN_LEFT_BOTTOM:
448 lcl_correctRotation_Left_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
449 break;
450 case LABEL_ALIGN_RIGHT_TOP:
451 lcl_correctRotation_Right_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
452 break;
453 case LABEL_ALIGN_RIGHT_BOTTOM:
454 lcl_correctRotation_Right_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
455 break;
456 default: //LABEL_ALIGN_CENTER
457 break;
460 xShape2DText->setPosition( awt::Point(
461 static_cast<sal_Int32>(aOldPos.X + fXCorrection )
462 , static_cast<sal_Int32>(aOldPos.Y + fYCorrection ) ) );
465 } //namespace chart
467 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */