LCOV - code coverage report
Current view: top level - chart2/source/view/diagram - VDiagram.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 326 361 90.3 %
Date: 2015-06-13 12:38:46 Functions: 18 19 94.7 %
Legend: Lines: hit not hit

          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 "VDiagram.hxx"
      21             : #include "PropertyMapper.hxx"
      22             : #include "ViewDefines.hxx"
      23             : #include "Stripe.hxx"
      24             : #include "macros.hxx"
      25             : #include "ObjectIdentifier.hxx"
      26             : #include "DiagramHelper.hxx"
      27             : #include "BaseGFXHelper.hxx"
      28             : #include "CommonConverters.hxx"
      29             : #include "ChartTypeHelper.hxx"
      30             : #include "ThreeDHelper.hxx"
      31             : #include "defines.hxx"
      32             : #include <editeng/unoprnms.hxx>
      33             : #include <com/sun/star/drawing/FillStyle.hpp>
      34             : #include <com/sun/star/drawing/LineStyle.hpp>
      35             : #include <com/sun/star/drawing/ProjectionMode.hpp>
      36             : #include <com/sun/star/drawing/ShadeMode.hpp>
      37             : #include <com/sun/star/lang/XUnoTunnel.hpp>
      38             : #include <com/sun/star/lang/XTypeProvider.hpp>
      39             : #include <svx/unoshape.hxx>
      40             : #include <svx/scene3d.hxx>
      41             : #include <svx/e3dsceneupdater.hxx>
      42             : 
      43             : namespace chart
      44             : {
      45             : using namespace ::com::sun::star;
      46             : using namespace ::com::sun::star::chart2;
      47             : 
      48        1053 : VDiagram::VDiagram(
      49             :     const uno::Reference<XDiagram> & xDiagram, const drawing::Direction3D& rPreferredAspectRatio,
      50             :     sal_Int32 nDimension )
      51             :     : m_xTarget(NULL)
      52             :     , m_xShapeFactory(NULL)
      53             :     , m_pShapeFactory(NULL)
      54             :     , m_xOuterGroupShape(NULL)
      55             :     , m_xCoordinateRegionShape(NULL)
      56             :     , m_xWall2D(NULL)
      57             :     , m_nDimensionCount(nDimension)
      58             :     , m_xDiagram(xDiagram)
      59             :     , m_aPreferredAspectRatio(rPreferredAspectRatio)
      60             :     , m_xAspectRatio3D()
      61             :     , m_fXAnglePi(0)
      62             :     , m_fYAnglePi(0)
      63             :     , m_fZAnglePi(0)
      64        1053 :     , m_bRightAngledAxes(false)
      65             : {
      66        1053 :     if( m_nDimensionCount == 3)
      67             :     {
      68          55 :         uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY );
      69          55 :         ThreeDHelper::getRotationAngleFromDiagram( xSourceProp, m_fXAnglePi, m_fYAnglePi, m_fZAnglePi );
      70         110 :         if( ChartTypeHelper::isSupportingRightAngledAxes(
      71         110 :                 DiagramHelper::getChartTypeByIndex( m_xDiagram, 0 ) ) )
      72             :         {
      73          49 :             if(xSourceProp.is())
      74          49 :                 xSourceProp->getPropertyValue("RightAngledAxes") >>= m_bRightAngledAxes;
      75          49 :             if( m_bRightAngledAxes )
      76             :             {
      77          36 :                 ThreeDHelper::adaptRadAnglesForRightAngledAxes( m_fXAnglePi, m_fYAnglePi );
      78          36 :                 m_fZAnglePi=0.0;
      79             :             }
      80          55 :         }
      81             :     }
      82        1053 : }
      83             : 
      84        1053 : VDiagram::~VDiagram()
      85             : {
      86        1053 : }
      87             : 
      88        1053 : void VDiagram::init(
      89             :     const uno::Reference< drawing::XShapes >& xTarget, const uno::Reference< lang::XMultiServiceFactory >& xFactory )
      90             : {
      91             :     OSL_PRECOND(xFactory.is(), "no proper initialization parameters");
      92             : 
      93        1053 :     m_xTarget  = xTarget;
      94        1053 :     m_xShapeFactory = xFactory;
      95        1053 :     m_pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(xFactory);
      96        1053 : }
      97             : 
      98        1053 : void VDiagram::createShapes( const awt::Point& rPos, const awt::Size& rSize )
      99             : {
     100        1053 :     m_aAvailablePosIncludingAxes = rPos;
     101        1053 :     m_aAvailableSizeIncludingAxes = rSize;
     102             : 
     103        1053 :     if( m_nDimensionCount == 3 )
     104          55 :         createShapes_3d();
     105             :     else
     106         998 :         createShapes_2d();
     107        1053 : }
     108             : 
     109        3070 : ::basegfx::B2IRectangle VDiagram::adjustPosAndSize( const awt::Point& rPos, const awt::Size& rSize )
     110             : {
     111        3070 :     ::basegfx::B2IRectangle aAllowedRect( BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes,m_aAvailableSizeIncludingAxes) );
     112        3070 :     ::basegfx::B2IRectangle aNewInnerRect( BaseGFXHelper::makeRectangle(rPos,rSize) );
     113        3070 :     aNewInnerRect.intersect( aAllowedRect );
     114             : 
     115        3070 :     if( m_nDimensionCount == 3 )
     116         153 :         aNewInnerRect = adjustPosAndSize_3d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
     117             :     else
     118        2917 :         aNewInnerRect = adjustPosAndSize_2d( BaseGFXHelper::B2IRectangleToAWTPoint(aNewInnerRect), BaseGFXHelper::B2IRectangleToAWTSize(aNewInnerRect) );
     119             : 
     120        3070 :     return aNewInnerRect;
     121             : }
     122             : 
     123        3915 : ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_2d( const awt::Point& rPos, const awt::Size& rAvailableSize )
     124             : {
     125        3915 :     m_aCurrentPosWithoutAxes = rPos;
     126        3915 :     m_aCurrentSizeWithoutAxes = rAvailableSize;
     127        3915 :     if( m_aPreferredAspectRatio.DirectionX > 0 && m_aPreferredAspectRatio.DirectionY > 0)
     128             :     {
     129             :         //do not change aspect ratio
     130          70 :         awt::Size  aAspectRatio( static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME),
     131         140 :                                  static_cast<sal_Int32>(m_aPreferredAspectRatio.DirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME ));
     132             :         m_aCurrentSizeWithoutAxes = awt::Size( AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
     133          70 :                         rAvailableSize, aAspectRatio ) );
     134             :         //center diagram position
     135             :         m_aCurrentPosWithoutAxes = awt::Point( AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
     136          70 :             rPos, rAvailableSize, m_aCurrentSizeWithoutAxes ) );
     137             : 
     138             :     }
     139             : 
     140        3915 :     if( m_xWall2D.is() )
     141             :     {
     142        3915 :         m_xWall2D->setSize( m_aCurrentSizeWithoutAxes);
     143        3915 :         m_xWall2D->setPosition(m_aCurrentPosWithoutAxes);
     144             :     }
     145             : 
     146        3915 :     return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
     147             : }
     148             : 
     149         998 : void VDiagram::createShapes_2d()
     150             : {
     151             :     OSL_PRECOND(m_pShapeFactory && m_xTarget.is() && m_xShapeFactory.is(), "is not proper initialized");
     152         998 :     if (!m_pShapeFactory || !m_xTarget.is() || !m_xShapeFactory.is())
     153         998 :         return;
     154             : 
     155             :     //create group shape
     156         998 :     uno::Reference< drawing::XShapes > xOuterGroup_Shapes = m_pShapeFactory->createGroup2D(m_xTarget);
     157         998 :     m_xOuterGroupShape = uno::Reference<drawing::XShape>( xOuterGroup_Shapes, uno::UNO_QUERY );
     158             : 
     159        1996 :     uno::Reference< drawing::XShapes > xGroupForWall( m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"PlotAreaExcludingAxes") );
     160             : 
     161             :     //create independent group shape as container for datapoints and such things
     162             :     {
     163         998 :         uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID");
     164         998 :         m_xCoordinateRegionShape = uno::Reference<drawing::XShape>( xShapes, uno::UNO_QUERY );
     165             :     }
     166             : 
     167         998 :     bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
     168             : 
     169             :     //add back wall
     170             :     {
     171         998 :         AbstractShapeFactory* pShapeFactory = AbstractShapeFactory::getOrCreateShapeFactory(m_xShapeFactory);
     172        1996 :         m_xWall2D = pShapeFactory->createRectangle(
     173        1996 :                 xGroupForWall );
     174             : 
     175         998 :         uno::Reference< beans::XPropertySet > xProp( m_xWall2D, uno::UNO_QUERY );
     176         998 :         if( xProp.is())
     177             :         {
     178             :             try
     179             :             {
     180             :                 OSL_ENSURE( m_xDiagram.is(), "Invalid Diagram model" );
     181         998 :                 if( m_xDiagram.is() )
     182             :                 {
     183         998 :                     uno::Reference< beans::XPropertySet > xWallProp( m_xDiagram->getWall());
     184         998 :                     if( xWallProp.is())
     185         998 :                         PropertyMapper::setMappedProperties( xProp, xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties() );
     186             :                 }
     187         998 :                 if( !bAddFloorAndWall )
     188             :                 {
     189             :                     //we always need this object as dummy object for correct scene dimensions
     190             :                     //but it should not be visible in this case:
     191          33 :                     AbstractShapeFactory::makeShapeInvisible( m_xWall2D );
     192             :                 }
     193             :                 else
     194             :                 {
     195             :                     //CID for selection handling
     196         965 :                     OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
     197         965 :                     xProp->setPropertyValue( UNO_NAME_MISC_OBJ_NAME, uno::makeAny( aWallCID ) );
     198             :                 }
     199             :             }
     200           0 :             catch( const uno::Exception& e )
     201             :             {
     202             :                 ASSERT_EXCEPTION( e );
     203             :             }
     204         998 :         }
     205             : 
     206             :     }
     207             : 
     208             :     //position and size for diagram
     209        1996 :     adjustPosAndSize_2d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
     210             : }
     211             : 
     212         318 : E3dScene* lcl_getE3dScene( const uno::Reference< drawing::XShape >& xShape )
     213             : {
     214         318 :     E3dScene* pRet=NULL;
     215         318 :     uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY );
     216         636 :     uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY );
     217         318 :     if(xUnoTunnel.is()&&xTypeProvider.is())
     218             :     {
     219         318 :         SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() ));
     220         318 :         if(pSvxShape)
     221             :         {
     222         318 :             SdrObject* pObj = pSvxShape->GetSdrObject();
     223         318 :             if( pObj && pObj->ISA(E3dScene) )
     224         318 :                 pRet = static_cast<E3dScene*>(pObj);
     225             :         }
     226             :     }
     227         636 :     return pRet;
     228             : }
     229             : 
     230          55 : void lcl_setLightSources(
     231             :     const uno::Reference< beans::XPropertySet > & xSource,
     232             :     const uno::Reference< beans::XPropertySet > & xDest )
     233             : {
     234          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1,
     235          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_1));
     236          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2,
     237          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_2));
     238          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3,
     239          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_3));
     240          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4,
     241          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_4));
     242          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5,
     243          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_5));
     244          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6,
     245          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_6));
     246          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7,
     247          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_7));
     248          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8,
     249          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTON_8));
     250             : 
     251          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1,
     252          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_1));
     253          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2,
     254          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_2));
     255          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3,
     256          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_3));
     257          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4,
     258          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_4));
     259          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5,
     260          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_5));
     261          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6,
     262          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_6));
     263          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7,
     264          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_7));
     265          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8,
     266          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTDIRECTION_8));
     267             : 
     268          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1,
     269          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_1));
     270          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2,
     271          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_2));
     272          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3,
     273          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_3));
     274          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4,
     275          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_4));
     276          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5,
     277          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_5));
     278          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6,
     279          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_6));
     280          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7,
     281          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_7));
     282          55 :     xDest->setPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8,
     283          55 :                              xSource->getPropertyValue( UNO_NAME_3D_SCENE_LIGHTCOLOR_8));
     284          55 : }
     285             : 
     286             : namespace
     287             : {
     288             : 
     289         196 : void lcl_ensureScaleValue( double& rfScale )
     290             : {
     291             :     OSL_ENSURE(rfScale>0, "calculation error for automatic 3D height in chart");
     292         196 :     if( rfScale<0 )
     293           0 :         rfScale = 1.0;
     294         196 :     else if( rfScale<0.2 )
     295           0 :         rfScale = 0.2;
     296         196 :     else if( rfScale>5.0 )
     297           0 :         rfScale = 5.0;
     298         196 : }
     299             : 
     300             : }
     301             : 
     302         208 : void VDiagram::adjustAspectRatio3d( const awt::Size& rAvailableSize )
     303             : {
     304             :     OSL_PRECOND(m_xAspectRatio3D.is(), "created shape offers no XPropertySet");
     305         208 :     if( m_xAspectRatio3D.is())
     306             :     {
     307             :         try
     308             :         {
     309         208 :             double fScaleX = m_aPreferredAspectRatio.DirectionX;
     310         208 :             double fScaleY = m_aPreferredAspectRatio.DirectionY;
     311         208 :             double fScaleZ = m_aPreferredAspectRatio.DirectionZ;
     312             : 
     313             :             //normalize scale factors
     314             :             {
     315         208 :                 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
     316         208 :                 fScaleX/=fMax;
     317         208 :                 fScaleY/=fMax;
     318         208 :                 fScaleZ/=fMax;
     319             :             }
     320             : 
     321         208 :             if( fScaleX<0 || fScaleY<0 || fScaleZ<0 )
     322             :             {
     323             :                 //calculate automatic 3D aspect ratio that fits good into the given 2D area
     324         196 :                 double fW = rAvailableSize.Width;
     325         196 :                 double fH = rAvailableSize.Height;
     326             : 
     327         196 :                 double sx = fabs(sin(m_fXAnglePi));
     328         196 :                 double sy = fabs(sin(m_fYAnglePi));
     329         196 :                 double cz = fabs(cos(m_fZAnglePi));
     330         196 :                 double sz = fabs(sin(m_fZAnglePi));
     331             : 
     332         196 :                 if(m_bRightAngledAxes)
     333             :                 {
     334             :                     //base equations:
     335             :                     //fH*zoomfactor == sx*fScaleZ + fScaleY;
     336             :                     //fW*zoomfactor == sy*fScaleZ + fScaleX;
     337             : 
     338         144 :                     if( fScaleX>0 && fScaleZ>0 )
     339             :                     {
     340             :                         //calculate fScaleY:
     341         200 :                         if( !::basegfx::fTools::equalZero(fW) )
     342             :                         {
     343         100 :                             fScaleY = (fH/fW)*(sy*fScaleZ+fScaleX)-(sx*fScaleZ);
     344         100 :                             lcl_ensureScaleValue( fScaleY );
     345             :                         }
     346             :                         else
     347           0 :                             fScaleY = 1.0;//looking from top or bottom the height is irrelevant
     348             :                     }
     349          44 :                     else if( fScaleY>0 && fScaleZ>0 )
     350             :                     {
     351             :                         //calculate fScaleX:
     352          88 :                         if( !::basegfx::fTools::equalZero(fH) )
     353             :                         {
     354          44 :                             fScaleX = (fW/fH)*(sx*fScaleZ+fScaleY)-(sy*fScaleZ);
     355          44 :                             lcl_ensureScaleValue(fScaleX);
     356             :                         }
     357             :                         else
     358           0 :                             fScaleX = 1.0;//looking from top or bottom height is irrelevant
     359             :                     }
     360             :                     else
     361             :                     {
     362             :                         //todo
     363             :                         OSL_FAIL("not implemented yet");
     364             : 
     365           0 :                         if( fScaleX<0 )
     366           0 :                             fScaleX = 1.0;
     367           0 :                         if( fScaleY<0 )
     368           0 :                             fScaleY = 1.0;
     369           0 :                         if( fScaleZ<0 )
     370           0 :                             fScaleZ = 1.0;
     371             :                     }
     372             :                 }
     373             :                 else
     374             :                 {
     375             :                     //base equations:
     376             :                     //fH*zoomfactor == cz*fScaleY + sz*fScaleX;
     377             :                     //fW*zoomfactor == cz*fScaleX + sz*fScaleY;
     378             :                     //==>  fScaleY*(fH*sz-fW*cz) == fScaleX*(fW*sz-fH*cz);
     379          52 :                     if( fScaleX>0 && fScaleZ>0 )
     380             :                     {
     381             :                         //calculate fScaleY:
     382          52 :                         double fDivide = fH*sz-fW*cz;
     383          52 :                         if( !::basegfx::fTools::equalZero(fDivide) )
     384             :                         {
     385          52 :                             fScaleY = fScaleX*(fW*sz-fH*cz) / fDivide;
     386          52 :                             lcl_ensureScaleValue(fScaleY);
     387             :                         }
     388             :                         else
     389           0 :                             fScaleY = 1.0;//looking from top or bottom the height is irrelevant
     390             : 
     391             :                     }
     392           0 :                     else if( fScaleY>0 && fScaleZ>0 )
     393             :                     {
     394             :                         //calculate fScaleX:
     395           0 :                         double fDivide = fW*sz-fH*cz;
     396           0 :                         if( !::basegfx::fTools::equalZero(fDivide) )
     397             :                         {
     398           0 :                             fScaleX = fScaleY*(fH*sz-fW*cz) / fDivide;
     399           0 :                             lcl_ensureScaleValue(fScaleX);
     400             :                         }
     401             :                         else
     402           0 :                             fScaleX = 1.0;//looking from top or bottom height is irrelevant
     403             :                     }
     404             :                     else
     405             :                     {
     406             :                         //todo
     407             :                         OSL_FAIL("not implemented yet");
     408             : 
     409           0 :                         if( fScaleX<0 )
     410           0 :                             fScaleX = 1.0;
     411           0 :                         if( fScaleY<0 )
     412           0 :                             fScaleY = 1.0;
     413           0 :                         if( fScaleZ<0 )
     414           0 :                             fScaleZ = 1.0;
     415             :                     }
     416             :                 }
     417             :             }
     418             : 
     419             :             //normalize scale factors
     420             :             {
     421         208 :                 double fMax = std::max( std::max( fScaleX, fScaleY) , fScaleZ );
     422         208 :                 fScaleX/=fMax;
     423         208 :                 fScaleY/=fMax;
     424         208 :                 fScaleZ/=fMax;
     425             :             }
     426             : 
     427             :             // identity matrix
     428         208 :             ::basegfx::B3DHomMatrix aResult;
     429             :             aResult.translate( -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     430             :                             -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     431         208 :                             -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
     432         208 :             aResult.scale( fScaleX, fScaleY, fScaleZ );
     433             :             aResult.translate( FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     434             :                             FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0,
     435         208 :                             FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0 );
     436             : 
     437             :             // To get the 3D aspect ratio's effect on the 2D scene size, the scene's 2D size needs to be adapted to
     438             :             // 3D content changes here. The tooling class remembers the current 3D transformation stack
     439             :             // and in its destructor, calculates a new 2D SnapRect for the scene and it's modified 3D geometry.
     440         416 :             E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
     441             : 
     442         208 :             m_xAspectRatio3D->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
     443         416 :                 , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aResult )) );
     444             :         }
     445           0 :         catch( const uno::Exception& e )
     446             :         {
     447             :             ASSERT_EXCEPTION( e );
     448             :         }
     449             :     }
     450         208 : }
     451             : 
     452         208 : ::basegfx::B2IRectangle VDiagram::adjustPosAndSize_3d( const awt::Point& rPos, const awt::Size& rAvailableSize )
     453             : {
     454         208 :     adjustAspectRatio3d( rAvailableSize );
     455             : 
     456             :     //do not change aspect ratio of 3D scene with 2D bound rect
     457             :     m_aCurrentSizeWithoutAxes = AbstractShapeFactory::calculateNewSizeRespectingAspectRatio(
     458         208 :                     rAvailableSize, m_xOuterGroupShape->getSize() );
     459         208 :     m_xOuterGroupShape->setSize( m_aCurrentSizeWithoutAxes );
     460             : 
     461             :     //center diagram position
     462             :     m_aCurrentPosWithoutAxes= AbstractShapeFactory::calculateTopLeftPositionToCenterObject(
     463         208 :          rPos, rAvailableSize, m_aCurrentSizeWithoutAxes );
     464         208 :     m_xOuterGroupShape->setPosition(m_aCurrentPosWithoutAxes);
     465             : 
     466         208 :     return ::basegfx::B2IRectangle( BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes) );
     467             : }
     468             : 
     469          55 : void VDiagram::createShapes_3d()
     470             : {
     471             :     OSL_PRECOND(m_pShapeFactory && m_xTarget.is() && m_xShapeFactory.is(), "is not proper initialized");
     472          55 :     if (!m_pShapeFactory || !m_xTarget.is() || !m_xShapeFactory.is())
     473          55 :         return;
     474             : 
     475             :     //create shape
     476         165 :     m_xOuterGroupShape = uno::Reference< drawing::XShape >(
     477         110 :             m_pShapeFactory->createGroup3D( m_xTarget, "PlotAreaExcludingAxes" ), uno::UNO_QUERY);
     478             : 
     479             :     uno::Reference< drawing::XShapes > xOuterGroup_Shapes =
     480          55 :             uno::Reference<drawing::XShapes>( m_xOuterGroupShape, uno::UNO_QUERY );
     481             : 
     482             :     //create additional group to manipulate the aspect ratio of the whole diagram:
     483          55 :     xOuterGroup_Shapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, OUString() );
     484             : 
     485          55 :     m_xAspectRatio3D = uno::Reference< beans::XPropertySet >( xOuterGroup_Shapes, uno::UNO_QUERY );
     486             : 
     487          55 :     bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram );
     488             : 
     489          55 :     const bool bDoubleSided = false;
     490          55 :     const bool bFlatNormals = true;
     491             : 
     492             :     //add walls
     493             :     {
     494          55 :         uno::Reference< beans::XPropertySet > xWallProp( NULL );
     495          55 :         if( m_xDiagram.is() )
     496          55 :             xWallProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getWall());
     497             : 
     498         110 :         OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
     499          55 :         if( !bAddFloorAndWall )
     500           6 :             aWallCID.clear();
     501         110 :         uno::Reference< drawing::XShapes > xWallGroup_Shapes( m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, aWallCID ) );
     502             : 
     503          55 :         CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
     504          55 :         CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
     505             : 
     506             :         //add left wall
     507             :         {
     508          55 :             short nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 3 : 1;
     509          55 :             double xPos = 0.0;
     510          55 :             if( CuboidPlanePosition_Right==eLeftWallPos )
     511           0 :                 xPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
     512             :             Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     513             :                 , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
     514          55 :                 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
     515          55 :             if( CuboidPlanePosition_Right==eLeftWallPos )
     516             :             {
     517           0 :                 nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 2 : 0;
     518             :                 aStripe = Stripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     519             :                     , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     520           0 :                     , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) );
     521             :             }
     522          55 :             aStripe.InvertNormal(true);
     523             : 
     524             :             uno::Reference< drawing::XShape > xShape =
     525             :                 m_pShapeFactory->createStripe( xWallGroup_Shapes, aStripe
     526          55 :                     , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
     527          55 :             if( !bAddFloorAndWall )
     528             :             {
     529             :                 //we always need this object as dummy object for correct scene dimensions
     530             :                 //but it should not be visible in this case:
     531           6 :                 AbstractShapeFactory::makeShapeInvisible( xShape );
     532          55 :             }
     533             :         }
     534             :         //add back wall
     535             :         {
     536          55 :             short nRotatedTexture = 0;
     537          55 :             double zPos = 0.0;
     538          55 :             if( CuboidPlanePosition_Front==eBackWallPos )
     539           0 :                     zPos = FIXED_SIZE_FOR_3D_CHART_VOLUME;
     540             :             Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
     541             :                 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0)
     542          55 :                 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
     543          55 :             if( CuboidPlanePosition_Front==eBackWallPos )
     544             :             {
     545             :                 aStripe = Stripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos)
     546             :                 , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0)
     547           0 :                 , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) );
     548           0 :                 nRotatedTexture = 3;
     549             :             }
     550          55 :             aStripe.InvertNormal(true);
     551             : 
     552             :             uno::Reference< drawing::XShape > xShape =
     553             :                 m_pShapeFactory->createStripe(xWallGroup_Shapes, aStripe
     554          55 :                     , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals );
     555          55 :             if( !bAddFloorAndWall )
     556             :             {
     557             :                 //we always need this object as dummy object for correct scene dimensions
     558             :                 //but it should not be visible in this case:
     559           6 :                 AbstractShapeFactory::makeShapeInvisible( xShape );
     560          55 :             }
     561          55 :         }
     562             :     }
     563             : 
     564             :     try
     565             :     {
     566          55 :         uno::Reference< beans::XPropertySet > xSourceProp( m_xDiagram, uno::UNO_QUERY_THROW );
     567         110 :         uno::Reference< beans::XPropertySet > xDestProp( m_xOuterGroupShape, uno::UNO_QUERY_THROW );
     568             : 
     569             :         //perspective
     570             :         {
     571             :             //ignore distance and focal length from file format and model completely
     572             :             //use vrp only to indicate the distance of the camera and thus influence the perspective
     573          55 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_DISTANCE, uno::makeAny(
     574          55 :                                         static_cast<sal_Int32>(ThreeDHelper::getCameraDistance( xSourceProp ))));
     575          55 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE,
     576          55 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_PERSPECTIVE));
     577             :         }
     578             : 
     579             :         //light
     580             :         {
     581          55 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE,
     582          55 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_SHADE_MODE));
     583          55 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR,
     584          55 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_AMBIENTCOLOR));
     585          55 :             xDestProp->setPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING,
     586          55 :                                         xSourceProp->getPropertyValue( UNO_NAME_3D_SCENE_TWO_SIDED_LIGHTING));
     587          55 :             lcl_setLightSources( xSourceProp, xDestProp );
     588             :         }
     589             : 
     590             :         //rotation
     591             :         {
     592             :             //set diagrams rotation is set exclusively via the transformation matrix
     593             :             //don't set a camera at all!
     594             :             //the camera's rotation is incorporated into this matrix
     595             : 
     596          55 :             ::basegfx::B3DHomMatrix aEffectiveTranformation;
     597          55 :             aEffectiveTranformation.translate(-FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0, -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0, -FIXED_SIZE_FOR_3D_CHART_VOLUME/2.0);
     598             : 
     599          55 :             if(!m_bRightAngledAxes)
     600          19 :                 aEffectiveTranformation.rotate(m_fXAnglePi,m_fYAnglePi,m_fZAnglePi);
     601             :             else
     602          36 :                 aEffectiveTranformation.shearXY(m_fYAnglePi,-m_fXAnglePi);
     603             : 
     604             :             //#i98497# 3D charts are rendered with wrong size
     605         110 :             E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
     606          55 :             xDestProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX,
     607         110 :                     uno::makeAny( BaseGFXHelper::B3DHomMatrixToHomogenMatrix( aEffectiveTranformation ) ) );
     608          55 :         }
     609             :     }
     610           0 :     catch( const uno::Exception & ex )
     611             :     {
     612             :         ASSERT_EXCEPTION( ex );
     613             :     }
     614             : 
     615             :     //add floor plate
     616             :     {
     617          55 :         uno::Reference< beans::XPropertySet > xFloorProp( NULL );
     618          55 :         if( m_xDiagram.is() )
     619          55 :             xFloorProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getFloor());
     620             : 
     621             :         Stripe aStripe( drawing::Position3D(0,0,0)
     622             :             , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME)
     623          55 :             , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) );
     624          55 :         aStripe.InvertNormal(true);
     625             : 
     626             :         uno::Reference< drawing::XShape > xShape =
     627             :             m_pShapeFactory->createStripe(xOuterGroup_Shapes, aStripe
     628         110 :                 , xFloorProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, 0, bFlatNormals );
     629             : 
     630          55 :         CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) );
     631          55 :         if( !bAddFloorAndWall || (CuboidPlanePosition_Bottom!=eBottomPos) )
     632             :         {
     633             :             //we always need this object as dummy object for correct scene dimensions
     634             :             //but it should not be visible in this case:
     635           6 :             AbstractShapeFactory::makeShapeInvisible( xShape );
     636             :         }
     637             :         else
     638             :         {
     639          49 :             OUString aFloorCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_FLOOR, OUString() ) );//@todo read CID from model
     640          49 :             AbstractShapeFactory::setShapeName( xShape, aFloorCID );
     641          55 :         }
     642             :     }
     643             : 
     644             :     //create an additional scene for the smaller inner coordinate region:
     645             :     {
     646          55 :         uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup3D( xOuterGroup_Shapes,"testonly;CooContainer=XXX_CID" );
     647          55 :         m_xCoordinateRegionShape = uno::Reference< drawing::XShape >( xShapes, uno::UNO_QUERY );
     648             : 
     649         110 :         uno::Reference< beans::XPropertySet > xShapeProp( m_xCoordinateRegionShape, uno::UNO_QUERY );
     650             :         OSL_ENSURE(xShapeProp.is(), "created shape offers no XPropertySet");
     651          55 :         if( xShapeProp.is())
     652             :         {
     653             :             try
     654             :             {
     655          55 :                 double fXScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
     656          55 :                 double fYScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
     657          55 :                 double fZScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME;
     658             : 
     659          55 :                 ::basegfx::B3DHomMatrix aM;
     660          55 :                 aM.translate(GRID_TO_WALL_DISTANCE/fXScale, GRID_TO_WALL_DISTANCE/fYScale, GRID_TO_WALL_DISTANCE/fZScale);
     661          55 :                 aM.scale( fXScale, fYScale, fZScale );
     662         110 :                 E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape ));
     663          55 :                 xShapeProp->setPropertyValue( UNO_NAME_3D_TRANSFORM_MATRIX
     664         110 :                     , uno::makeAny(BaseGFXHelper::B3DHomMatrixToHomogenMatrix(aM)) );
     665             :             }
     666           0 :             catch( const uno::Exception& e )
     667             :             {
     668             :                 ASSERT_EXCEPTION( e );
     669             :             }
     670          55 :         }
     671             :     }
     672             : 
     673          55 :     m_aCurrentPosWithoutAxes = m_aAvailablePosIncludingAxes;
     674          55 :     m_aCurrentSizeWithoutAxes = m_aAvailableSizeIncludingAxes;
     675          55 :     adjustPosAndSize_3d( m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes );
     676             : }
     677             : 
     678        5218 : basegfx::B2IRectangle VDiagram::getCurrentRectangle() const
     679             : {
     680        5218 :     return BaseGFXHelper::makeRectangle(m_aCurrentPosWithoutAxes,m_aCurrentSizeWithoutAxes);
     681             : }
     682             : 
     683        1011 : void VDiagram::reduceToMimimumSize()
     684             : {
     685        1011 :     if( m_xOuterGroupShape.is() )
     686             :     {
     687        1011 :         awt::Size aMaxSize( m_aAvailableSizeIncludingAxes );
     688        1011 :         awt::Point aMaxPos( m_aAvailablePosIncludingAxes );
     689             : 
     690        1011 :         sal_Int32 nNewWidth = aMaxSize.Width/3;
     691        1011 :         sal_Int32 nNewHeight = aMaxSize.Height/3;
     692        1011 :         awt::Size aNewSize( nNewWidth, nNewHeight );
     693        1011 :         awt::Point aNewPos( aMaxPos );
     694        1011 :         aNewPos.X += nNewWidth;
     695        1011 :         aNewPos.Y += nNewHeight;
     696             : 
     697        1011 :         adjustPosAndSize( aNewPos, aNewSize );
     698             :     }
     699        1011 : }
     700             : 
     701        2059 : ::basegfx::B2IRectangle VDiagram::adjustInnerSize( const ::basegfx::B2IRectangle& rConsumedOuterRect )
     702             : {
     703        2059 :     awt::Point aNewPos = m_aCurrentPosWithoutAxes;
     704        2059 :     awt::Size aNewSize = m_aCurrentSizeWithoutAxes;
     705             : 
     706             :     basegfx::B2IRectangle aAvailableOuterRect =
     707        2059 :         BaseGFXHelper::makeRectangle(m_aAvailablePosIncludingAxes, m_aAvailableSizeIncludingAxes);
     708             : 
     709        2059 :     sal_Int32 nDeltaWidth = aAvailableOuterRect.getWidth() - rConsumedOuterRect.getWidth();
     710        2059 :     sal_Int32 nDeltaHeight = aAvailableOuterRect.getHeight() - rConsumedOuterRect.getHeight();
     711        2059 :     if( (aNewSize.Width + nDeltaWidth) < aAvailableOuterRect.getWidth()/3 )
     712           0 :         nDeltaWidth = aAvailableOuterRect.getWidth()/3 - aNewSize.Width;
     713        2059 :     aNewSize.Width += nDeltaWidth;
     714             : 
     715        2059 :     if( (aNewSize.Height + nDeltaHeight) < aAvailableOuterRect.getHeight()/3 )
     716          31 :         nDeltaHeight = aAvailableOuterRect.getHeight()/3 - aNewSize.Height;
     717        2059 :     aNewSize.Height += nDeltaHeight;
     718             : 
     719        2059 :     sal_Int32 nDiffLeft = rConsumedOuterRect.getMinX() - aAvailableOuterRect.getMinX();
     720        2059 :     sal_Int32 nDiffRight = aAvailableOuterRect.getMaxX() - rConsumedOuterRect.getMaxX();
     721        2059 :     if( nDiffLeft >= 0 )
     722        1520 :         aNewPos.X -= nDiffLeft;
     723         539 :     else if( nDiffRight >= 0 )
     724             :     {
     725         517 :         if( nDiffRight > -nDiffLeft )
     726           6 :             aNewPos.X += abs(nDiffLeft);
     727         511 :         else if( nDiffRight > abs(nDeltaWidth) )
     728           3 :             aNewPos.X += nDiffRight;
     729             :         else
     730         508 :             aNewPos.X += abs(nDeltaWidth);
     731             :     }
     732             : 
     733        2059 :     sal_Int32 nDiffUp = rConsumedOuterRect.getMinY() - aAvailableOuterRect.getMinY();
     734        2059 :     sal_Int32 nDiffDown = aAvailableOuterRect.getMaxY() - rConsumedOuterRect.getMaxY();
     735        2059 :     if( nDiffUp >= 0 )
     736        1325 :         aNewPos.Y -= nDiffUp;
     737         734 :     else if( nDiffDown >= 0 )
     738             :     {
     739         717 :         if( nDiffDown > -nDiffUp )
     740         481 :             aNewPos.Y += abs(nDiffUp);
     741         236 :         else if( nDiffDown > abs(nDeltaHeight) )
     742           9 :             aNewPos.Y += nDiffDown;
     743             :         else
     744         227 :             aNewPos.Y += abs(nDeltaHeight);
     745             :     }
     746             : 
     747        2059 :     return adjustPosAndSize( aNewPos, aNewSize );
     748             : }
     749             : 
     750          57 : } //namespace chart
     751             : 
     752             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11