diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-01-11 15:02:14 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-01-11 19:15:44 +0100 |
commit | 18bc9ea75daf4eb3520a4d0ef6649d92261012a6 (patch) | |
tree | 6ef7917e159d4e2a5c65678ba7e440c0039778da | |
parent | 610c089cf545ae3346262cc1e78fd21a9e1f8efb (diff) |
replace XTransformation with more efficient class
this UNO interface is not being used an a real UNO API, so replace it
with something that doesn't pass around 3 doubles in a Sequence
Change-Id: I39d8ae03a3e861daba87f46686c0f93815bb1805
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128292
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | chart2/source/view/axes/VCartesianGrid.cxx | 18 | ||||
-rw-r--r-- | chart2/source/view/charttypes/BarChart.cxx | 10 | ||||
-rw-r--r-- | chart2/source/view/inc/Linear3DTransformation.hxx | 20 | ||||
-rw-r--r-- | chart2/source/view/inc/PlottingPositionHelper.hxx | 45 | ||||
-rw-r--r-- | chart2/source/view/inc/VPolarTransformation.hxx | 19 | ||||
-rw-r--r-- | chart2/source/view/main/Linear3DTransformation.cxx | 65 | ||||
-rw-r--r-- | chart2/source/view/main/PlottingPositionHelper.cxx | 24 | ||||
-rw-r--r-- | chart2/source/view/main/VPolarTransformation.cxx | 33 |
8 files changed, 152 insertions, 82 deletions
diff --git a/chart2/source/view/axes/VCartesianGrid.cxx b/chart2/source/view/axes/VCartesianGrid.cxx index 283703ba5984..d681bf07874b 100644 --- a/chart2/source/view/axes/VCartesianGrid.cxx +++ b/chart2/source/view/axes/VCartesianGrid.cxx @@ -138,11 +138,11 @@ void GridLinePoints::update( double fScaledTickValue ) static void addLine2D( drawing::PointSequenceSequence& rPoints, sal_Int32 nIndex , const GridLinePoints& rScaledLogicPoints - , const Reference< XTransformation > & xTransformation + , const XTransformation2& rTransformation ) { - drawing::Position3D aPA = SequenceToPosition3D( xTransformation->transform( rScaledLogicPoints.P0 ) ); - drawing::Position3D aPB = SequenceToPosition3D( xTransformation->transform( rScaledLogicPoints.P1 ) ); + drawing::Position3D aPA = rTransformation.transform( SequenceToPosition3D(rScaledLogicPoints.P0) ); + drawing::Position3D aPB = rTransformation.transform( SequenceToPosition3D(rScaledLogicPoints.P1) ); rPoints.getArray()[nIndex] = { { static_cast<sal_Int32>(aPA.PositionX), static_cast<sal_Int32>(aPA.PositionY) }, @@ -151,13 +151,13 @@ static void addLine2D( drawing::PointSequenceSequence& rPoints, sal_Int32 nIndex static void addLine3D( std::vector<std::vector<css::drawing::Position3D>>& rPoints, sal_Int32 nIndex , const GridLinePoints& rBasePoints - , const Reference< XTransformation > & xTransformation ) + , const XTransformation2 & rTransformation ) { - drawing::Position3D aPoint = SequenceToPosition3D( xTransformation->transform( rBasePoints.P0 ) ); + drawing::Position3D aPoint =rTransformation.transform( rBasePoints.P0 ); AddPointToPoly( rPoints, aPoint, nIndex ); - aPoint = SequenceToPosition3D( xTransformation->transform( rBasePoints.P1 ) ); + aPoint = rTransformation.transform( rBasePoints.P1 ); AddPointToPoly( rPoints, aPoint, nIndex ); - aPoint = SequenceToPosition3D( xTransformation->transform( rBasePoints.P2 ) ); + aPoint = rTransformation.transform( rBasePoints.P2 ); AddPointToPoly( rPoints, aPoint, nIndex ); } @@ -255,7 +255,7 @@ void VCartesianGrid::createShapes() if( !tick.bPaintIt ) continue; aGridLinePoints.update( tick.fScaledTickValue ); - addLine2D( aPoints, nRealPointCount, aGridLinePoints, m_pPosHelper->getTransformationScaledLogicToScene() ); + addLine2D( aPoints, nRealPointCount, aGridLinePoints, *m_pPosHelper->getTransformationScaledLogicToScene() ); nRealPointCount++; } aPoints.realloc(nRealPointCount); @@ -295,7 +295,7 @@ void VCartesianGrid::createShapes() } aGridLinePoints.update( tick.fScaledTickValue ); - addLine3D( aPoints, nPolyIndex, aGridLinePoints, m_pPosHelper->getTransformationScaledLogicToScene() ); + addLine3D( aPoints, nPolyIndex, aGridLinePoints, *m_pPosHelper->getTransformationScaledLogicToScene() ); nRealPointCount+=3; ++nPolyIndex; } diff --git a/chart2/source/view/charttypes/BarChart.cxx b/chart2/source/view/charttypes/BarChart.cxx index efcf1dd13831..57dc851e2035 100644 --- a/chart2/source/view/charttypes/BarChart.cxx +++ b/chart2/source/view/charttypes/BarChart.cxx @@ -802,13 +802,13 @@ void BarChart::createShapes() drawing::Position3D aLogicRightDeepTop (fLogicX-fLogicBarWidth/2.0,fLogicYStart+fMiddleHeight,fLogicZ+fLogicBarDepth/2.0); drawing::Position3D aLogicTopTop (fLogicX,fLogicYStart+fMiddleHeight+fTopHeight,fLogicZ); - uno::Reference< XTransformation > xTransformation = pSubPosHelper->getTransformationScaledLogicToScene(); + ::chart::XTransformation2* pTransformation = pSubPosHelper->getTransformationScaledLogicToScene(); //transformation 3) -> 4) - drawing::Position3D aTransformedBottom ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicBottom) ) ) ); - drawing::Position3D aTransformedLeftBottomFront ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicLeftBottomFront) ) ) ); - drawing::Position3D aTransformedRightDeepTop ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicRightDeepTop) ) ) ); - drawing::Position3D aTransformedTopTop ( SequenceToPosition3D( xTransformation->transform( Position3DToSequence(aLogicTopTop) ) ) ); + drawing::Position3D aTransformedBottom ( pTransformation->transform( aLogicBottom ) ); + drawing::Position3D aTransformedLeftBottomFront ( pTransformation->transform( aLogicLeftBottomFront ) ); + drawing::Position3D aTransformedRightDeepTop ( pTransformation->transform( aLogicRightDeepTop ) ); + drawing::Position3D aTransformedTopTop ( pTransformation->transform( aLogicTopTop ) ); drawing::Direction3D aSize = aTransformedRightDeepTop - aTransformedLeftBottomFront; drawing::Direction3D aTopSize( aTransformedTopTop - aTransformedRightDeepTop ); diff --git a/chart2/source/view/inc/Linear3DTransformation.hxx b/chart2/source/view/inc/Linear3DTransformation.hxx index 4b7f243e0c1d..8074364bb3a4 100644 --- a/chart2/source/view/inc/Linear3DTransformation.hxx +++ b/chart2/source/view/inc/Linear3DTransformation.hxx @@ -18,29 +18,23 @@ */ #pragma once -#include <cppuhelper/implbase.hxx> -#include <com/sun/star/chart2/XTransformation.hpp> +#include "PlottingPositionHelper.hxx" #include <com/sun/star/drawing/HomogenMatrix.hpp> namespace chart { -class Linear3DTransformation : public ::cppu::WeakImplHelper< - css::chart2::XTransformation - > +class Linear3DTransformation : public XTransformation2 { public: Linear3DTransformation( const css::drawing::HomogenMatrix& rHomMatrix, bool bSwapXAndY ); virtual ~Linear3DTransformation() override; - // ____ XTransformation ____ - /// @see css::chart2::XTransformation - virtual css::uno::Sequence< double > SAL_CALL transform( - const css::uno::Sequence< double >& rSourceValues ) override; - /// @see css::chart2::XTransformation - virtual sal_Int32 SAL_CALL getSourceDimension() override; - /// @see css::chart2::XTransformation - virtual sal_Int32 SAL_CALL getTargetDimension() override; + // ____ XTransformation2 ____ + virtual css::drawing::Position3D transform( + const css::drawing::Position3D& rSourceValues ) const override; + virtual css::drawing::Position3D transform( + const css::uno::Sequence< double >& rSourceValues ) const override; private: css::drawing::HomogenMatrix m_Matrix; diff --git a/chart2/source/view/inc/PlottingPositionHelper.hxx b/chart2/source/view/inc/PlottingPositionHelper.hxx index 14e22375df17..81486bcdb669 100644 --- a/chart2/source/view/inc/PlottingPositionHelper.hxx +++ b/chart2/source/view/inc/PlottingPositionHelper.hxx @@ -44,6 +44,45 @@ namespace chart class ShapeFactory; +/** allows the transformation of numeric values from one + coordinate-system into another. Values may be transformed using + any mapping. + This is a non-UNO variant of the css::chart2::XTransformation interface, + but using more efficient calling and returning types. + */ +class XTransformation2 +{ +public: + virtual ~XTransformation2(); + /** transforms the given input data tuple, given in the source + coordinate system, according to the internal transformation + rules, into a tuple of transformed coordinates in the + destination coordinate system. + + <p>Note that both coordinate systems may have different + dimensions, e.g., if a transformation does simply a projection + into a lower-dimensional space.</p> + + @param aValues a source tuple of data that is to be + transformed. The length of this sequence must be + equivalent to the dimension of the source coordinate + system. + + @return the transformed data tuple. The length of this + sequence is equal to the dimension of the output + coordinate system. + + @throws ::com::sun::star::lang::IllegalArgumentException + if the dimension of the input vector is not equal to the + dimension given in getSourceDimension(). + */ + virtual css::drawing::Position3D transform( + const css::drawing::Position3D& rSourceValues ) const = 0; + virtual css::drawing::Position3D transform( + const css::uno::Sequence< double >& rSourceValues ) const = 0; +}; + + class PlottingPositionHelper { public: @@ -74,7 +113,7 @@ public: inline void doLogicScaling( css::drawing::Position3D& rPos ) const; - virtual css::uno::Reference< css::chart2::XTransformation > + virtual ::chart::XTransformation2* getTransformationScaledLogicToScene() const; virtual css::drawing::Position3D @@ -123,7 +162,7 @@ protected: //member ::basegfx::B3DHomMatrix m_aMatrixScreenToScene; //this is calculated based on m_aScales and m_aMatrixScreenToScene - mutable css::uno::Reference< css::chart2::XTransformation > m_xTransformationLogicToScene; + mutable std::unique_ptr< ::chart::XTransformation2 > m_xTransformationLogicToScene; bool m_bSwapXAndY;//e.g. true for bar chart and false for column chart @@ -156,7 +195,7 @@ public: const ::basegfx::B3DHomMatrix& getUnitCartesianToScene() const { return m_aUnitCartesianToScene;} - virtual css::uno::Reference< css::chart2::XTransformation > + virtual ::chart::XTransformation2* getTransformationScaledLogicToScene() const override; //the resulting values provided by the following 3 methods should be used diff --git a/chart2/source/view/inc/VPolarTransformation.hxx b/chart2/source/view/inc/VPolarTransformation.hxx index 2d8aacc764f3..788916a6c90e 100644 --- a/chart2/source/view/inc/VPolarTransformation.hxx +++ b/chart2/source/view/inc/VPolarTransformation.hxx @@ -19,28 +19,21 @@ #pragma once #include "PlottingPositionHelper.hxx" -#include <cppuhelper/implbase.hxx> -#include <com/sun/star/chart2/XTransformation.hpp> namespace chart { -class VPolarTransformation : public ::cppu::WeakImplHelper< - css::chart2::XTransformation - > +class VPolarTransformation : public XTransformation2 { public: VPolarTransformation( const PolarPlottingPositionHelper& rPositionHelper ); virtual ~VPolarTransformation() override; - // ____ XTransformation ____ - /// @see css::chart2::XTransformation - virtual css::uno::Sequence< double > SAL_CALL transform( - const css::uno::Sequence< double >& rSourceValues ) override; - /// @see css::chart2::XTransformation - virtual sal_Int32 SAL_CALL getSourceDimension() override; - /// @see css::chart2::XTransformation - virtual sal_Int32 SAL_CALL getTargetDimension() override; + // ____ XTransformation2 ____ + virtual css::drawing::Position3D transform( + const css::uno::Sequence< double >& rSourceValues ) const override; + virtual css::drawing::Position3D transform( + const css::drawing::Position3D& rSourceValues ) const override; private: PolarPlottingPositionHelper m_aPositionHelper; diff --git a/chart2/source/view/main/Linear3DTransformation.cxx b/chart2/source/view/main/Linear3DTransformation.cxx index f6f403ba26f3..0d723ef3454f 100644 --- a/chart2/source/view/main/Linear3DTransformation.cxx +++ b/chart2/source/view/main/Linear3DTransformation.cxx @@ -34,36 +34,35 @@ namespace chart Linear3DTransformation::~Linear3DTransformation() {} -// ____ XTransformation ____ -Sequence< double > SAL_CALL Linear3DTransformation::transform( - const Sequence< double >& rSourceValues ) +// ____ XTransformation2 ____ +css::drawing::Position3D Linear3DTransformation::transform( + const Sequence< double >& rSourceValues ) const { double fX = rSourceValues[0]; double fY = rSourceValues[1]; double fZ = rSourceValues[2]; if(m_bSwapXAndY) std::swap(fX,fY); - Sequence< double > aNewVec(3); - auto pNewVec = aNewVec.getArray(); + css::drawing::Position3D aNewVec; double fZwi; fZwi = m_Matrix.Line1.Column1 * fX + m_Matrix.Line1.Column2 * fY + m_Matrix.Line1.Column3 * fZ + m_Matrix.Line1.Column4; - pNewVec[0] = fZwi; + aNewVec.PositionX = fZwi; fZwi = m_Matrix.Line2.Column1 * fX + m_Matrix.Line2.Column2 * fY + m_Matrix.Line2.Column3 * fZ + m_Matrix.Line2.Column4; - pNewVec[1] = fZwi; + aNewVec.PositionY = fZwi; fZwi = m_Matrix.Line3.Column1 * fX + m_Matrix.Line3.Column2 * fY + m_Matrix.Line3.Column3 * fZ + m_Matrix.Line3.Column4; - pNewVec[2] = fZwi; + aNewVec.PositionZ = fZwi; fZwi = m_Matrix.Line4.Column1 * fX + m_Matrix.Line4.Column2 * fY @@ -71,21 +70,53 @@ Sequence< double > SAL_CALL Linear3DTransformation::transform( + m_Matrix.Line4.Column4; if(fZwi != 1.0 && fZwi != 0.0) { - pNewVec[0] /= fZwi; - pNewVec[1] /= fZwi; - pNewVec[2] /= fZwi; + aNewVec.PositionX /= fZwi; + aNewVec.PositionY /= fZwi; + aNewVec.PositionZ /= fZwi; } return aNewVec; } -sal_Int32 SAL_CALL Linear3DTransformation::getSourceDimension() +css::drawing::Position3D Linear3DTransformation::transform( + const css::drawing::Position3D& rSourceValues ) const { - return 3; -} + double fX = rSourceValues.PositionX; + double fY = rSourceValues.PositionY; + double fZ = rSourceValues.PositionZ; + if(m_bSwapXAndY) + std::swap(fX,fY); + css::drawing::Position3D aNewVec; + double fZwi; -sal_Int32 SAL_CALL Linear3DTransformation::getTargetDimension() -{ - return 3; + fZwi = m_Matrix.Line1.Column1 * fX + + m_Matrix.Line1.Column2 * fY + + m_Matrix.Line1.Column3 * fZ + + m_Matrix.Line1.Column4; + aNewVec.PositionX = fZwi; + + fZwi = m_Matrix.Line2.Column1 * fX + + m_Matrix.Line2.Column2 * fY + + m_Matrix.Line2.Column3 * fZ + + m_Matrix.Line2.Column4; + aNewVec.PositionY = fZwi; + + fZwi = m_Matrix.Line3.Column1 * fX + + m_Matrix.Line3.Column2 * fY + + m_Matrix.Line3.Column3 * fZ + + m_Matrix.Line3.Column4; + aNewVec.PositionZ = fZwi; + + fZwi = m_Matrix.Line4.Column1 * fX + + m_Matrix.Line4.Column2 * fY + + m_Matrix.Line4.Column3 * fZ + + m_Matrix.Line4.Column4; + if(fZwi != 1.0 && fZwi != 0.0) + { + aNewVec.PositionX /= fZwi; + aNewVec.PositionY /= fZwi; + aNewVec.PositionZ /= fZwi; + } + return aNewVec; } } // namespace chart diff --git a/chart2/source/view/main/PlottingPositionHelper.cxx b/chart2/source/view/main/PlottingPositionHelper.cxx index 0c2084aae2e2..0a63747b0ecb 100644 --- a/chart2/source/view/main/PlottingPositionHelper.cxx +++ b/chart2/source/view/main/PlottingPositionHelper.cxx @@ -38,6 +38,8 @@ namespace chart using namespace ::com::sun::star; using namespace ::com::sun::star::chart2; +XTransformation2::~XTransformation2() {} + PlottingPositionHelper::PlottingPositionHelper() : m_bSwapXAndY( false ) , m_nXResolution( 1000 ) @@ -100,7 +102,7 @@ void PlottingPositionHelper::setScales( std::vector< ExplicitScaleData >&& rScal m_xTransformationLogicToScene = nullptr; } -uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScaledLogicToScene() const +::chart::XTransformation2* PlottingPositionHelper::getTransformationScaledLogicToScene() const { //this is a standard transformation for a cartesian coordinate system @@ -108,7 +110,7 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScale //we need to apply this transformation to each geometric object because of a bug/problem //of the old drawing layer (the UNO_NAME_3D_EXTRUDE_DEPTH is an integer value instead of a double ) - if(!m_xTransformationLogicToScene.is()) + if(!m_xTransformationLogicToScene) { ::basegfx::B3DHomMatrix aMatrix; double MinX = getLogicMinX(); @@ -162,9 +164,9 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScale aMatrix = m_aMatrixScreenToScene*aMatrix; - m_xTransformationLogicToScene = new Linear3DTransformation(B3DHomMatrixToHomogenMatrix( aMatrix ),m_bSwapXAndY); + m_xTransformationLogicToScene.reset(new Linear3DTransformation(B3DHomMatrixToHomogenMatrix( aMatrix ), m_bSwapXAndY)); } - return m_xTransformationLogicToScene; + return m_xTransformationLogicToScene.get(); } drawing::Position3D PlottingPositionHelper::transformLogicToScene( @@ -185,11 +187,9 @@ drawing::Position3D PlottingPositionHelper::transformScaledLogicToScene( drawing::Position3D aPos( fX, fY, fZ); - uno::Reference< XTransformation > xTransformation = + ::chart::XTransformation2* pTransformation = getTransformationScaledLogicToScene(); - uno::Sequence< double > aSeq = - xTransformation->transform( Position3DToSequence(aPos) ); - return SequenceToPosition3D(aSeq); + return pTransformation->transform( aPos ); } awt::Point PlottingPositionHelper::transformSceneToScreenPosition( const drawing::Position3D& rScenePosition3D @@ -409,11 +409,11 @@ void PolarPlottingPositionHelper::setScales( std::vector< ExplicitScaleData >&& return aRet; } -uno::Reference< XTransformation > PolarPlottingPositionHelper::getTransformationScaledLogicToScene() const +::chart::XTransformation2* PolarPlottingPositionHelper::getTransformationScaledLogicToScene() const { - if( !m_xTransformationLogicToScene.is() ) - m_xTransformationLogicToScene = new VPolarTransformation(*this); - return m_xTransformationLogicToScene; + if( !m_xTransformationLogicToScene ) + m_xTransformationLogicToScene.reset(new VPolarTransformation(*this)); + return m_xTransformationLogicToScene.get(); } double PolarPlottingPositionHelper::getWidthAngleDegree( double& fStartLogicValueOnAngleAxis, double& fEndLogicValueOnAngleAxis ) const diff --git a/chart2/source/view/main/VPolarTransformation.cxx b/chart2/source/view/main/VPolarTransformation.cxx index 6d3ba587fc9c..9d747d66c956 100644 --- a/chart2/source/view/main/VPolarTransformation.cxx +++ b/chart2/source/view/main/VPolarTransformation.cxx @@ -37,9 +37,9 @@ VPolarTransformation::~VPolarTransformation() { } -// ____ XTransformation ____ -Sequence< double > SAL_CALL VPolarTransformation::transform( - const Sequence< double >& rSourceValues ) +// ____ XTransformation2 ____ +css::drawing::Position3D VPolarTransformation::transform( + const Sequence< double >& rSourceValues ) const { double fScaledLogicAngle = rSourceValues[0]; double fScaledLogicRadius = rSourceValues[1]; @@ -58,17 +58,30 @@ Sequence< double > SAL_CALL VPolarTransformation::transform( //!! applying matrix to vector does ignore translation, so it is important to use a B3DPoint here instead of B3DVector ::basegfx::B3DPoint aPoint(fX,fY,fZ); ::basegfx::B3DPoint aRet = m_aUnitCartesianToScene * aPoint; - return B3DPointToSequence(aRet); + return css::drawing::Position3D(aRet.getX(), aRet.getY(), aRet.getZ()); } -sal_Int32 SAL_CALL VPolarTransformation::getSourceDimension() +css::drawing::Position3D VPolarTransformation::transform( + const css::drawing::Position3D& rSourceValues ) const { - return 3; -} + double fScaledLogicAngle = rSourceValues.PositionX; + double fScaledLogicRadius = rSourceValues.PositionY; -sal_Int32 SAL_CALL VPolarTransformation::getTargetDimension() -{ - return 3; + if( m_aPositionHelper.isSwapXAndY() ) + std::swap(fScaledLogicAngle,fScaledLogicRadius); + + double fAngleDegree = m_aPositionHelper.transformToAngleDegree( fScaledLogicAngle, false ); + double fAnglePi = basegfx::deg2rad(fAngleDegree); + double fRadius = m_aPositionHelper.transformToRadius( fScaledLogicRadius, false); + + double fX=fRadius*cos(fAnglePi); + double fY=fRadius*sin(fAnglePi); + double fZ=rSourceValues.PositionZ; + + //!! applying matrix to vector does ignore translation, so it is important to use a B3DPoint here instead of B3DVector + ::basegfx::B3DPoint aPoint(fX,fY,fZ); + ::basegfx::B3DPoint aRet = m_aUnitCartesianToScene * aPoint; + return css::drawing::Position3D(aRet.getX(), aRet.getY(), aRet.getZ()); } } // namespace chart |