blob: 25c7c96456c500196afbc0e574f8bd9a8613f590 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"
#include "LabelPositionHelper.hxx"
#include "PlottingPositionHelper.hxx"
#include "CommonConverters.hxx"
#include "PropertyMapper.hxx"
#include "ShapeFactory.hxx"
#include "macros.hxx"
#include "RelativeSizeHelper.hxx"
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
//.............................................................................
namespace chart
{
//.............................................................................
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
LabelPositionHelper::LabelPositionHelper(
PlottingPositionHelper* pPosHelper
, sal_Int32 nDimensionCount
, const uno::Reference< drawing::XShapes >& xLogicTarget
, ShapeFactory* pShapeFactory )
: m_pPosHelper(pPosHelper)
, m_nDimensionCount(nDimensionCount)
, m_xLogicTarget(xLogicTarget)
, m_pShapeFactory(pShapeFactory)
{
}
LabelPositionHelper::~LabelPositionHelper()
{
}
awt::Point LabelPositionHelper::transformSceneToScreenPosition( const drawing::Position3D& rScenePosition3D ) const
{
return PlottingPositionHelper::transformSceneToScreenPosition(
rScenePosition3D, m_xLogicTarget, m_pShapeFactory, m_nDimensionCount );
}
void LabelPositionHelper::changeTextAdjustment( tAnySequence& rPropValues, const tNameSequence& rPropNames, LabelAlignment eAlignment)
{
//HorizontalAdjustment
{
drawing::TextHorizontalAdjust eHorizontalAdjust = drawing::TextHorizontalAdjust_CENTER;
if( LABEL_ALIGN_RIGHT==eAlignment || LABEL_ALIGN_RIGHT_TOP==eAlignment || LABEL_ALIGN_RIGHT_BOTTOM==eAlignment )
eHorizontalAdjust = drawing::TextHorizontalAdjust_LEFT;
else if( LABEL_ALIGN_LEFT==eAlignment || LABEL_ALIGN_LEFT_TOP==eAlignment || LABEL_ALIGN_LEFT_BOTTOM==eAlignment )
eHorizontalAdjust = drawing::TextHorizontalAdjust_RIGHT;
uno::Any* pHorizontalAdjustAny = PropertyMapper::getValuePointer(rPropValues,rPropNames,C2U("TextHorizontalAdjust"));
if(pHorizontalAdjustAny)
*pHorizontalAdjustAny = uno::makeAny(eHorizontalAdjust);
}
//VerticalAdjustment
{
drawing::TextVerticalAdjust eVerticalAdjust = drawing::TextVerticalAdjust_CENTER;
if( LABEL_ALIGN_TOP==eAlignment || LABEL_ALIGN_RIGHT_TOP==eAlignment || LABEL_ALIGN_LEFT_TOP==eAlignment )
eVerticalAdjust = drawing::TextVerticalAdjust_BOTTOM;
else if( LABEL_ALIGN_BOTTOM==eAlignment || LABEL_ALIGN_RIGHT_BOTTOM==eAlignment || LABEL_ALIGN_LEFT_BOTTOM==eAlignment )
eVerticalAdjust = drawing::TextVerticalAdjust_TOP;
uno::Any* pVerticalAdjustAny = PropertyMapper::getValuePointer(rPropValues,rPropNames,C2U("TextVerticalAdjust"));
if(pVerticalAdjustAny)
*pVerticalAdjustAny = uno::makeAny(eVerticalAdjust);
}
}
void lcl_doDynamicFontResize( uno::Any* pAOldAndNewFontHeightAny
, const awt::Size& rOldReferenceSize
, const awt::Size& rNewReferenceSize )
{
double fOldFontHeight = 0, fNewFontHeight;
if( pAOldAndNewFontHeightAny && ( *pAOldAndNewFontHeightAny >>= fOldFontHeight ) )
{
fNewFontHeight = RelativeSizeHelper::calculate( fOldFontHeight, rOldReferenceSize, rNewReferenceSize );
*pAOldAndNewFontHeightAny = uno::makeAny(fNewFontHeight);
}
}
void LabelPositionHelper::doDynamicFontResize( tAnySequence& rPropValues
, const tNameSequence& rPropNames
, const uno::Reference< beans::XPropertySet >& xAxisModelProps
, const awt::Size& rNewReferenceSize
)
{
//-------------------------
//handle dynamic font resize:
awt::Size aOldReferenceSize;
if( xAxisModelProps->getPropertyValue( C2U("ReferencePageSize")) >>= aOldReferenceSize )
{
uno::Any* pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, C2U("CharHeight") );
lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, C2U("CharHeightAsian") );
lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
pAOldAndNewFontHeightAny = PropertyMapper::getValuePointer( rPropValues, rPropNames, C2U("CharHeightComplex") );
lcl_doDynamicFontResize( pAOldAndNewFontHeightAny, aOldReferenceSize, rNewReferenceSize );
}
}
namespace
{
void lcl_correctRotation_Left( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
{
//correct label positions for labels on a left side of something with a right centered alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree==0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi )/2.0;
if( bRotateAroundCenter )
rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi )/2.0;
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = fAnglePi-F_PI/2.0;
rfXCorrection = -aSize.Width *rtl::math::sin( beta )
-aSize.Height *rtl::math::cos( beta )/2.0;
if( bRotateAroundCenter )
rfYCorrection = -aSize.Width *rtl::math::cos( beta )/2.0;
else
rfYCorrection = -aSize.Width *rtl::math::cos( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = fAnglePi - F_PI;
rfXCorrection = -aSize.Width *rtl::math::cos( beta )
-aSize.Height*rtl::math::sin( beta )/2.0;
if( bRotateAroundCenter )
rfYCorrection = aSize.Width *rtl::math::sin( beta )/2.0;
else
rfYCorrection = aSize.Width *rtl::math::sin( beta );
}
else
{
double beta = 2*F_PI - fAnglePi;
rfXCorrection = -aSize.Height*rtl::math::sin( beta )/2.0;
if( bRotateAroundCenter )
rfYCorrection = aSize.Width*rtl::math::sin( beta )/2.0;
}
}
void lcl_correctRotation_Right( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
{
//correct label positions for labels on a right side of something with a left centered alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree== 0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi )/2.0;
if( bRotateAroundCenter )
rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi )/2.0;
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = F_PI - fAnglePi;
rfXCorrection = aSize.Width *rtl::math::cos( beta )
+ aSize.Height*rtl::math::sin( beta )/2.0;
if( bRotateAroundCenter )
rfYCorrection = aSize.Width *rtl::math::sin( beta )/2.0;
else
rfYCorrection = aSize.Width *rtl::math::sin( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = 3*F_PI/2.0 - fAnglePi;
rfXCorrection = aSize.Width *rtl::math::sin( beta )
+aSize.Height*rtl::math::cos( beta )/2.0;
if( bRotateAroundCenter )
rfYCorrection = -aSize.Width *rtl::math::cos( beta )/2.0;
else
rfYCorrection = -aSize.Width *rtl::math::cos( beta );
}
else
{
rfXCorrection = aSize.Height*rtl::math::sin( 2*F_PI - fAnglePi )/2.0;
if( bRotateAroundCenter )
rfYCorrection = -aSize.Width*rtl::math::sin( 2*F_PI - fAnglePi )/2.0;
}
}
void lcl_correctRotation_Top( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
{
//correct label positions for labels on top of something with a bottom centered alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree== 0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi )/2.0;
if( !bRotateAroundCenter )
rfXCorrection += aSize.Width*rtl::math::cos( fAnglePi )/2.0;
rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi )/2.0;
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = fAnglePi - F_PI/2.0;
rfXCorrection = aSize.Height*rtl::math::cos( beta )/2.0;
if( !bRotateAroundCenter )
rfXCorrection -= aSize.Width*rtl::math::sin( beta )/2.0;
rfYCorrection = -aSize.Width*rtl::math::cos( beta )/2.0
- aSize.Height*rtl::math::sin( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = fAnglePi - F_PI;
rfXCorrection = -aSize.Height *rtl::math::sin( beta )/2.0;
if( !bRotateAroundCenter )
rfXCorrection += aSize.Width *rtl::math::cos( beta )/2.0;
rfYCorrection = -aSize.Width *rtl::math::sin( beta )/2.0
-aSize.Height *rtl::math::cos( beta );
}
else
{
rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi )/2.0;
if( !bRotateAroundCenter )
rfXCorrection -= aSize.Width*rtl::math::cos( fAnglePi )/2.0;
rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi )/2.0;
}
}
void lcl_correctRotation_Bottom( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize, bool bRotateAroundCenter )
{
//correct label positions for labels below something with a top centered alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree==0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi )/2.0;
if( !bRotateAroundCenter )
rfXCorrection -= aSize.Width *rtl::math::cos( fAnglePi )/2.0;
rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi )/2.0;
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = fAnglePi-F_PI/2.0;
rfXCorrection = -aSize.Height*rtl::math::cos( beta )/2.0;
if( !bRotateAroundCenter )
rfXCorrection += aSize.Width *rtl::math::sin( beta )/2.0;
rfYCorrection = aSize.Width *rtl::math::cos( beta )/2.0
+aSize.Height*rtl::math::sin( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = 3*F_PI/2.0 - fAnglePi;
rfXCorrection = aSize.Height*rtl::math::cos( beta )/2.0;
if( !bRotateAroundCenter )
rfXCorrection -= aSize.Width *rtl::math::sin( beta )/2.0;
rfYCorrection = aSize.Height*rtl::math::sin( beta )
+aSize.Width*rtl::math::cos( beta )/2.0;
}
else
{
double beta = 2*F_PI - fAnglePi;
rfXCorrection = aSize.Height*rtl::math::sin( beta )/2.0;
if( !bRotateAroundCenter )
rfXCorrection += aSize.Width*rtl::math::cos( beta )/2.0;
rfYCorrection = aSize.Width*rtl::math::sin( beta )/2.0;
}
}
void lcl_correctRotation_Left_Top( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize )
{
//correct position for labels at the left top corner of something with a bottom right alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree==0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi );
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = fAnglePi-F_PI/2.0;
rfXCorrection = -aSize.Width*rtl::math::sin( beta );
rfYCorrection = -aSize.Height*rtl::math::sin( beta )
-aSize.Width*rtl::math::cos( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = 3*F_PI/2.0 - fAnglePi;
rfXCorrection = -aSize.Height*rtl::math::cos( beta )
-aSize.Width*rtl::math::sin( beta );
rfYCorrection = -aSize.Height*rtl::math::sin( beta );
}
else
{
rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi );
}
}
void lcl_correctRotation_Left_Bottom( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize )
{
//correct position for labels at the left bottom corner of something with a top right alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree==0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi );
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = fAnglePi-F_PI/2.0;
rfXCorrection = -aSize.Width*rtl::math::sin( beta )
-aSize.Height*rtl::math::cos( beta );;
rfYCorrection = aSize.Height*rtl::math::sin( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = 3*F_PI/2.0 - fAnglePi;
rfXCorrection = -aSize.Width*rtl::math::sin( beta );
rfYCorrection = aSize.Width*rtl::math::cos( beta )
+aSize.Height*rtl::math::sin( beta );
}
else
{
rfYCorrection = -aSize.Width*rtl::math::sin( fAnglePi );
}
}
void lcl_correctRotation_Right_Top( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize )
{
//correct position for labels at the right top corner of something with a bottom left alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree==0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfXCorrection = aSize.Height*rtl::math::sin( fAnglePi );
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = fAnglePi-F_PI/2.0;
rfXCorrection = aSize.Width*rtl::math::sin( beta )
+aSize.Height*rtl::math::cos( beta );
rfYCorrection = -aSize.Height*rtl::math::sin( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = 3*F_PI/2.0 - fAnglePi;
rfXCorrection = aSize.Width*rtl::math::sin( beta );
rfYCorrection = -aSize.Width*rtl::math::cos( beta )
-aSize.Height*rtl::math::sin( beta );
}
else
{
rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi );
}
}
void lcl_correctRotation_Right_Bottom( double& rfXCorrection, double& rfYCorrection
, double fAnglePositiveDegree, const awt::Size& aSize )
{
//correct position for labels at the right bottom corner of something with a top left alignment
double fAnglePi = fAnglePositiveDegree*F_PI/180.0;
if( fAnglePositiveDegree==0.0 )
{
}
else if( fAnglePositiveDegree<= 90.0 )
{
rfYCorrection = aSize.Width*rtl::math::sin( fAnglePi );
}
else if( fAnglePositiveDegree<= 180.0 )
{
double beta = fAnglePi-F_PI/2.0;
rfXCorrection = aSize.Width*rtl::math::sin( beta );
rfYCorrection = aSize.Height*rtl::math::sin( beta )
+aSize.Width*rtl::math::cos( beta );
}
else if( fAnglePositiveDegree<= 270.0 )
{
double beta = 3*F_PI/2.0 - fAnglePi;
rfXCorrection = aSize.Height*rtl::math::cos( beta )
+aSize.Width*rtl::math::sin( beta );
rfYCorrection = aSize.Height*rtl::math::sin( beta );
}
else
{
rfXCorrection = -aSize.Height*rtl::math::sin( fAnglePi );
}
}
}//end anonymous namespace
void LabelPositionHelper::correctPositionForRotation( const uno::Reference< drawing::XShape >& xShape2DText
, LabelAlignment eLabelAlignment, const double fRotationAngle, bool bRotateAroundCenter )
{
if( !xShape2DText.is() )
return;
awt::Point aOldPos = xShape2DText->getPosition();
awt::Size aSize = xShape2DText->getSize();
double fYCorrection = 0.0;
double fXCorrection = 0.0;
double fAnglePositiveDegree = fRotationAngle;
while(fAnglePositiveDegree<0.0)
fAnglePositiveDegree+=360.0;
switch(eLabelAlignment)
{
case LABEL_ALIGN_LEFT:
lcl_correctRotation_Left( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
break;
case LABEL_ALIGN_RIGHT:
lcl_correctRotation_Right( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
break;
case LABEL_ALIGN_TOP:
lcl_correctRotation_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
break;
case LABEL_ALIGN_BOTTOM:
lcl_correctRotation_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize, bRotateAroundCenter );
break;
case LABEL_ALIGN_LEFT_TOP:
lcl_correctRotation_Left_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
break;
case LABEL_ALIGN_LEFT_BOTTOM:
lcl_correctRotation_Left_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
break;
case LABEL_ALIGN_RIGHT_TOP:
lcl_correctRotation_Right_Top( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
break;
case LABEL_ALIGN_RIGHT_BOTTOM:
lcl_correctRotation_Right_Bottom( fXCorrection, fYCorrection, fAnglePositiveDegree, aSize );
break;
default: //LABEL_ALIGN_CENTER
break;
}
xShape2DText->setPosition( awt::Point(
static_cast<sal_Int32>(aOldPos.X + fXCorrection )
, static_cast<sal_Int32>(aOldPos.Y + fYCorrection ) ) );
}
//.............................................................................
} //namespace chart
//.............................................................................