LCOV - code coverage report
Current view: top level - sd/source/ui/func - fumorph.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 255 0.0 %
Date: 2012-08-25 Functions: 0 15 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 622 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "fumorph.hxx"
      30                 :            : #include <svx/xfillit.hxx>
      31                 :            : #include <svx/xlineit.hxx>
      32                 :            : #include <vcl/msgbox.hxx>
      33                 :            : #include <svx/svdpool.hxx>
      34                 :            : #include <tools/poly.hxx>
      35                 :            : #include <svx/svdopath.hxx>
      36                 :            : #include <svx/svdogrp.hxx>
      37                 :            : #include <editeng/eeitem.hxx>
      38                 :            : 
      39                 :            : #include "View.hxx"
      40                 :            : #include "ViewShell.hxx"
      41                 :            : #include "Window.hxx"
      42                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      43                 :            : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      44                 :            : #include <basegfx/matrix/b2dhommatrix.hxx>
      45                 :            : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      46                 :            : 
      47                 :            : #include "strings.hrc"
      48                 :            : #include "sdresid.hxx"
      49                 :            : 
      50                 :            : #include "sdabstdlg.hxx"
      51                 :            : 
      52                 :            : // #i48168#
      53                 :            : #include <svx/svditer.hxx>
      54                 :            : 
      55                 :            : #include <basegfx/color/bcolor.hxx>
      56                 :            : 
      57                 :            : namespace sd {
      58                 :            : 
      59                 :            : #define  ITEMVALUE( ItemSet, Id, Cast ) ( ( (const Cast&) (ItemSet).Get( (Id) ) ).GetValue() )
      60 [ #  # ][ #  # ]:          0 : TYPEINIT1( FuMorph, FuPoor );
      61                 :            : 
      62                 :            : //////////////////////////////////////////////////////////////////////////////
      63                 :            : // constructor
      64                 :            : //
      65                 :          0 : FuMorph::FuMorph (
      66                 :            :     ViewShell* pViewSh,
      67                 :            :     ::sd::Window* pWin,
      68                 :            :     ::sd::View* pView,
      69                 :            :     SdDrawDocument* pDoc,
      70                 :            :     SfxRequest& rReq )
      71                 :          0 :     :   FuPoor(pViewSh, pWin, pView, pDoc, rReq)
      72                 :            : {
      73                 :          0 : }
      74                 :            : 
      75                 :          0 : FunctionReference FuMorph::Create(
      76                 :            :     ViewShell* pViewSh,
      77                 :            :     ::sd::Window* pWin,
      78                 :            :     ::sd::View* pView,
      79                 :            :     SdDrawDocument* pDoc,
      80                 :            :     SfxRequest& rReq
      81                 :            : )
      82                 :            : {
      83 [ #  # ][ #  # ]:          0 :     FunctionReference xFunc( new FuMorph( pViewSh, pWin, pView, pDoc, rReq ) );
      84         [ #  # ]:          0 :     xFunc->DoExecute(rReq);
      85                 :          0 :     return xFunc;
      86                 :            : }
      87                 :            : 
      88                 :          0 : void FuMorph::DoExecute( SfxRequest& )
      89                 :            : {
      90                 :          0 :     const SdrMarkList&  rMarkList = mpView->GetMarkedObjectList();
      91                 :            : 
      92         [ #  # ]:          0 :     if(rMarkList.GetMarkCount() == 2)
      93                 :            :     {
      94                 :            :         // Clones erzeugen
      95 [ #  # ][ #  # ]:          0 :         SdrObject*  pObj1 = rMarkList.GetMark(0)->GetMarkedSdrObj();
      96 [ #  # ][ #  # ]:          0 :         SdrObject*  pObj2 = rMarkList.GetMark(1)->GetMarkedSdrObj();
      97         [ #  # ]:          0 :         SdrObject*  pCloneObj1 = pObj1->Clone();
      98         [ #  # ]:          0 :         SdrObject*  pCloneObj2 = pObj2->Clone();
      99                 :            : 
     100                 :            :         // Text am Clone loeschen, da wir sonst kein richtiges PathObj bekommen
     101         [ #  # ]:          0 :         pCloneObj1->SetOutlinerParaObject(NULL);
     102         [ #  # ]:          0 :         pCloneObj2->SetOutlinerParaObject(NULL);
     103                 :            : 
     104                 :            :         // Path-Objekte erzeugen
     105         [ #  # ]:          0 :         SdrObject*  pPolyObj1 = pCloneObj1->ConvertToPolyObj(sal_False, sal_False);
     106         [ #  # ]:          0 :         SdrObject*  pPolyObj2 = pCloneObj2->ConvertToPolyObj(sal_False, sal_False);
     107         [ #  # ]:          0 :         SdAbstractDialogFactory* pFact = SdAbstractDialogFactory::Create();
     108 [ #  # ][ #  # ]:          0 :         AbstractMorphDlg* pDlg = pFact ? pFact->CreateMorphDlg( static_cast< ::Window*>(mpWindow), pObj1, pObj2 ) : 0;
     109 [ #  # ][ #  # ]:          0 :         if(pPolyObj1 && pPolyObj2 && pDlg && (pDlg->Execute() == RET_OK))
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     110                 :            :         {
     111         [ #  # ]:          0 :             B2DPolyPolygonList_impl aPolyPolyList;
     112         [ #  # ]:          0 :             ::basegfx::B2DPolyPolygon aPolyPoly1;
     113         [ #  # ]:          0 :             ::basegfx::B2DPolyPolygon aPolyPoly2;
     114                 :            : 
     115         [ #  # ]:          0 :             pDlg->SaveSettings();
     116                 :            : 
     117                 :            :             // #i48168# Not always is the pPolyObj1/pPolyObj2 a SdrPathObj, it may also be a group object
     118                 :            :             // containing SdrPathObjs. To get the polygons, i add two iters here
     119         [ #  # ]:          0 :             SdrObjListIter aIter1(*pPolyObj1);
     120         [ #  # ]:          0 :             SdrObjListIter aIter2(*pPolyObj2);
     121                 :            : 
     122         [ #  # ]:          0 :             while(aIter1.IsMore())
     123                 :            :             {
     124         [ #  # ]:          0 :                 SdrObject* pObj = aIter1.Next();
     125 [ #  # ][ #  # ]:          0 :                 if(pObj && pObj->ISA(SdrPathObj))
         [ #  # ][ #  # ]
                 [ #  # ]
     126         [ #  # ]:          0 :                     aPolyPoly1.append(((SdrPathObj*)pObj)->GetPathPoly());
     127                 :            :             }
     128                 :            : 
     129         [ #  # ]:          0 :             while(aIter2.IsMore())
     130                 :            :             {
     131         [ #  # ]:          0 :                 SdrObject* pObj = aIter2.Next();
     132 [ #  # ][ #  # ]:          0 :                 if(pObj && pObj->ISA(SdrPathObj))
         [ #  # ][ #  # ]
                 [ #  # ]
     133         [ #  # ]:          0 :                     aPolyPoly2.append(((SdrPathObj*)pObj)->GetPathPoly());
     134                 :            :             }
     135                 :            : 
     136                 :            :             // Morphing durchfuehren
     137 [ #  # ][ #  # ]:          0 :             if(aPolyPoly1.count() && aPolyPoly2.count())
         [ #  # ][ #  # ]
                 [ #  # ]
     138                 :            :             {
     139 [ #  # ][ #  # ]:          0 :                 aPolyPoly1 = ::basegfx::tools::correctOrientations(aPolyPoly1);
                 [ #  # ]
     140         [ #  # ]:          0 :                 aPolyPoly1.removeDoublePoints();
     141 [ #  # ][ #  # ]:          0 :                 ::basegfx::B2VectorOrientation eIsClockwise1(::basegfx::tools::getOrientation(aPolyPoly1.getB2DPolygon(0L)));
                 [ #  # ]
     142                 :            : 
     143 [ #  # ][ #  # ]:          0 :                 aPolyPoly2 = ::basegfx::tools::correctOrientations(aPolyPoly2);
                 [ #  # ]
     144         [ #  # ]:          0 :                 aPolyPoly2.removeDoublePoints();
     145 [ #  # ][ #  # ]:          0 :                 ::basegfx::B2VectorOrientation eIsClockwise2(::basegfx::tools::getOrientation(aPolyPoly2.getB2DPolygon(0L)));
                 [ #  # ]
     146                 :            : 
     147                 :            :                 // set same orientation
     148         [ #  # ]:          0 :                 if(eIsClockwise1 != eIsClockwise2)
     149         [ #  # ]:          0 :                     aPolyPoly2.flip();
     150                 :            : 
     151                 :            :                 // force same poly count
     152 [ #  # ][ #  # ]:          0 :                 if(aPolyPoly1.count() < aPolyPoly2.count())
                 [ #  # ]
     153         [ #  # ]:          0 :                     ImpAddPolys(aPolyPoly1, aPolyPoly2);
     154 [ #  # ][ #  # ]:          0 :                 else if(aPolyPoly2.count() < aPolyPoly1.count())
                 [ #  # ]
     155         [ #  # ]:          0 :                     ImpAddPolys(aPolyPoly2, aPolyPoly1);
     156                 :            : 
     157                 :            :                 // use orientation flag from dialog
     158 [ #  # ][ #  # ]:          0 :                 if(!pDlg->IsOrientationFade())
     159         [ #  # ]:          0 :                     aPolyPoly2.flip();
     160                 :            : 
     161                 :            :                 // force same point counts
     162 [ #  # ][ #  # ]:          0 :                 for( sal_uInt32 a(0L); a < aPolyPoly1.count(); a++ )
     163                 :            :                 {
     164         [ #  # ]:          0 :                     ::basegfx::B2DPolygon aSub1(aPolyPoly1.getB2DPolygon(a));
     165         [ #  # ]:          0 :                     ::basegfx::B2DPolygon aSub2(aPolyPoly2.getB2DPolygon(a));
     166                 :            : 
     167 [ #  # ][ #  # ]:          0 :                     if(aSub1.count() < aSub2.count())
                 [ #  # ]
     168         [ #  # ]:          0 :                         ImpEqualizePolyPointCount(aSub1, aSub2);
     169 [ #  # ][ #  # ]:          0 :                     else if(aSub2.count() < aSub1.count())
                 [ #  # ]
     170         [ #  # ]:          0 :                         ImpEqualizePolyPointCount(aSub2, aSub1);
     171                 :            : 
     172         [ #  # ]:          0 :                     aPolyPoly1.setB2DPolygon(a, aSub1);
     173         [ #  # ]:          0 :                     aPolyPoly2.setB2DPolygon(a, aSub2);
     174 [ #  # ][ #  # ]:          0 :                 }
     175                 :            : 
     176 [ #  # ][ #  # ]:          0 :                 if(ImpMorphPolygons(aPolyPoly1, aPolyPoly2, pDlg->GetFadeSteps(), aPolyPolyList))
                 [ #  # ]
     177                 :            :                 {
     178         [ #  # ]:          0 :                     String aString(mpView->GetDescriptionOfMarkedObjects());
     179                 :            : 
     180         [ #  # ]:          0 :                     aString.Append(sal_Unicode(' '));
     181 [ #  # ][ #  # ]:          0 :                     aString.Append(String(SdResId(STR_UNDO_MORPHING)));
         [ #  # ][ #  # ]
     182                 :            : 
     183         [ #  # ]:          0 :                     mpView->BegUndo(aString);
     184 [ #  # ][ #  # ]:          0 :                     ImpInsertPolygons(aPolyPolyList, pDlg->IsAttributeFade(), pObj1, pObj2);
     185 [ #  # ][ #  # ]:          0 :                     mpView->EndUndo();
     186                 :            :                 }
     187                 :            : 
     188         [ #  # ]:          0 :                 for( size_t i = 0, n = aPolyPolyList.size(); i < n; ++i ) {
     189 [ #  # ][ #  # ]:          0 :                     delete aPolyPolyList[ i ];
                 [ #  # ]
     190                 :            :                 }
     191 [ #  # ][ #  # ]:          0 :             }
     192                 :            :         }
     193 [ #  # ][ #  # ]:          0 :         delete pDlg;
     194         [ #  # ]:          0 :         SdrObject::Free( pCloneObj1 );
     195         [ #  # ]:          0 :         SdrObject::Free( pCloneObj2 );
     196                 :            : 
     197         [ #  # ]:          0 :         SdrObject::Free( pPolyObj1 );
     198         [ #  # ]:          0 :         SdrObject::Free( pPolyObj2 );
     199                 :            :     }
     200                 :          0 : }
     201                 :            : 
     202                 :          0 : ::basegfx::B2DPolygon ImpGetExpandedPolygon(
     203                 :            :     const ::basegfx::B2DPolygon& rCandidate,
     204                 :            :     sal_uInt32 nNum
     205                 :            : )
     206                 :            : {
     207 [ #  # ][ #  # ]:          0 :     if(rCandidate.count() && nNum && rCandidate.count() != nNum)
         [ #  # ][ #  # ]
     208                 :            :     {
     209                 :            :         // length of step in dest poly
     210         [ #  # ]:          0 :         ::basegfx::B2DPolygon aRetval;
     211 [ #  # ][ #  # ]:          0 :         const double fStep(::basegfx::tools::getLength(rCandidate) / (double)(rCandidate.isClosed() ? nNum : nNum - 1L));
                 [ #  # ]
     212                 :          0 :         double fDestPos(0.0);
     213                 :          0 :         double fSrcPos(0.0);
     214                 :          0 :         sal_uInt32 nSrcPos(0L);
     215 [ #  # ][ #  # ]:          0 :         sal_uInt32 nSrcPosNext((nSrcPos + 1L == rCandidate.count()) ? 0L : nSrcPos + 1L);
     216 [ #  # ][ #  # ]:          0 :         double fNextSrcLen(::basegfx::B2DVector(rCandidate.getB2DPoint(nSrcPos) - rCandidate.getB2DPoint(nSrcPosNext)).getLength());
                 [ #  # ]
     217                 :            : 
     218         [ #  # ]:          0 :         for(sal_uInt32 b(0L); b < nNum; b++)
     219                 :            :         {
     220                 :            :             // calc fDestPos in source
     221         [ #  # ]:          0 :             while(fSrcPos + fNextSrcLen < fDestPos)
     222                 :            :             {
     223                 :          0 :                 fSrcPos += fNextSrcLen;
     224                 :          0 :                 nSrcPos++;
     225 [ #  # ][ #  # ]:          0 :                 nSrcPosNext = (nSrcPos + 1L == rCandidate.count()) ? 0L : nSrcPos + 1L;
     226 [ #  # ][ #  # ]:          0 :                 fNextSrcLen = ::basegfx::B2DVector(rCandidate.getB2DPoint(nSrcPos) - rCandidate.getB2DPoint(nSrcPosNext)).getLength();
                 [ #  # ]
     227                 :            :             }
     228                 :            : 
     229                 :            :             // fDestPos is between fSrcPos and (fSrcPos + fNextSrcLen)
     230                 :          0 :             const double fLenA((fDestPos - fSrcPos) / fNextSrcLen);
     231         [ #  # ]:          0 :             const ::basegfx::B2DPoint aOld1(rCandidate.getB2DPoint(nSrcPos));
     232         [ #  # ]:          0 :             const ::basegfx::B2DPoint aOld2(rCandidate.getB2DPoint(nSrcPosNext));
     233                 :          0 :             ::basegfx::B2DPoint aNewPoint(basegfx::interpolate(aOld1, aOld2, fLenA));
     234         [ #  # ]:          0 :             aRetval.append(aNewPoint);
     235                 :            : 
     236                 :            :             // next step
     237                 :          0 :             fDestPos += fStep;
     238                 :          0 :         }
     239                 :            : 
     240 [ #  # ][ #  # ]:          0 :         if(aRetval.count() >= 3L)
     241                 :            :         {
     242 [ #  # ][ #  # ]:          0 :             aRetval.setClosed(rCandidate.isClosed());
     243                 :            :         }
     244                 :            : 
     245 [ #  # ][ #  # ]:          0 :         return aRetval;
     246                 :            :     }
     247                 :            :     else
     248                 :            :     {
     249                 :          0 :         return rCandidate;
     250                 :            :     }
     251                 :            : }
     252                 :            : 
     253                 :            : //////////////////////////////////////////////////////////////////////////////
     254                 :            : // make the point count of the polygons equal in adding points
     255                 :            : //
     256                 :          0 : void FuMorph::ImpEqualizePolyPointCount(
     257                 :            :     ::basegfx::B2DPolygon& rSmall,
     258                 :            :     const ::basegfx::B2DPolygon& rBig
     259                 :            : )
     260                 :            : {
     261                 :            :     // create poly with equal point count
     262         [ #  # ]:          0 :     const sal_uInt32 nCnt(rBig.count());
     263         [ #  # ]:          0 :     ::basegfx::B2DPolygon aPoly1(ImpGetExpandedPolygon(rSmall, nCnt));
     264                 :            : 
     265                 :            :     // create transformation for rBig to do the compare
     266         [ #  # ]:          0 :     const ::basegfx::B2DRange aSrcSize(::basegfx::tools::getRange(rBig));
     267         [ #  # ]:          0 :     const ::basegfx::B2DPoint aSrcPos(aSrcSize.getCenter());
     268         [ #  # ]:          0 :     const ::basegfx::B2DRange aDstSize(::basegfx::tools::getRange(rSmall));
     269         [ #  # ]:          0 :     const ::basegfx::B2DPoint aDstPos(aDstSize.getCenter());
     270                 :            : 
     271         [ #  # ]:          0 :     basegfx::B2DHomMatrix aTrans(basegfx::tools::createTranslateB2DHomMatrix(-aSrcPos.getX(), -aSrcPos.getY()));
     272 [ #  # ][ #  # ]:          0 :     aTrans.scale(aDstSize.getWidth() / aSrcSize.getWidth(), aDstSize.getHeight() / aSrcSize.getHeight());
         [ #  # ][ #  # ]
                 [ #  # ]
     273         [ #  # ]:          0 :     aTrans.translate(aDstPos.getX(), aDstPos.getY());
     274                 :            : 
     275                 :            :     // transpose points to have smooth linear blending
     276         [ #  # ]:          0 :     ::basegfx::B2DPolygon aPoly2;
     277         [ #  # ]:          0 :     aPoly2.append(::basegfx::B2DPoint(), nCnt);
     278 [ #  # ][ #  # ]:          0 :     sal_uInt32 nInd(ImpGetNearestIndex(aPoly1, aTrans * rBig.getB2DPoint(0L)));
                 [ #  # ]
     279                 :            : 
     280         [ #  # ]:          0 :     for(sal_uInt32 a(0L); a < nCnt; a++)
     281                 :            :     {
     282 [ #  # ][ #  # ]:          0 :         aPoly2.setB2DPoint((a + nCnt - nInd) % nCnt, aPoly1.getB2DPoint(a));
     283                 :            :     }
     284                 :            : 
     285 [ #  # ][ #  # ]:          0 :     aPoly2.setClosed(rBig.isClosed());
     286 [ #  # ][ #  # ]:          0 :     rSmall = aPoly2;
         [ #  # ][ #  # ]
     287                 :          0 : }
     288                 :            : 
     289                 :            : //////////////////////////////////////////////////////////////////////////////
     290                 :            : //
     291                 :          0 : sal_uInt32 FuMorph::ImpGetNearestIndex(
     292                 :            :     const ::basegfx::B2DPolygon& rPoly,
     293                 :            :     const ::basegfx::B2DPoint& rPos
     294                 :            : )
     295                 :            : {
     296                 :          0 :     double fMinDist = 0.0;
     297                 :          0 :     sal_uInt32 nActInd = 0;
     298                 :            : 
     299         [ #  # ]:          0 :     for(sal_uInt32 a(0L); a < rPoly.count(); a++)
     300                 :            :     {
     301         [ #  # ]:          0 :         double fNewDist(::basegfx::B2DVector(rPoly.getB2DPoint(a) - rPos).getLength());
     302                 :            : 
     303 [ #  # ][ #  # ]:          0 :         if(!a || fNewDist < fMinDist)
     304                 :            :         {
     305                 :          0 :             fMinDist = fNewDist;
     306                 :          0 :             nActInd = a;
     307                 :            :         }
     308                 :            :     }
     309                 :            : 
     310                 :          0 :     return nActInd;
     311                 :            : }
     312                 :            : 
     313                 :            : //////////////////////////////////////////////////////////////////////////////
     314                 :            : // add to a point reduced polys until count is same
     315                 :            : //
     316                 :          0 : void FuMorph::ImpAddPolys(
     317                 :            :     ::basegfx::B2DPolyPolygon& rSmaller,
     318                 :            :     const ::basegfx::B2DPolyPolygon& rBigger
     319                 :            : )
     320                 :            : {
     321         [ #  # ]:          0 :     while(rSmaller.count() < rBigger.count())
     322                 :            :     {
     323 [ #  # ][ #  # ]:          0 :         const ::basegfx::B2DPolygon aToBeCopied(rBigger.getB2DPolygon(rSmaller.count()));
     324         [ #  # ]:          0 :         const ::basegfx::B2DRange aToBeCopiedPolySize(::basegfx::tools::getRange(aToBeCopied));
     325         [ #  # ]:          0 :         ::basegfx::B2DPoint aNewPoint(aToBeCopiedPolySize.getCenter());
     326         [ #  # ]:          0 :         ::basegfx::B2DPolygon aNewPoly;
     327                 :            : 
     328 [ #  # ][ #  # ]:          0 :         const ::basegfx::B2DRange aSrcSize(::basegfx::tools::getRange(rBigger.getB2DPolygon(0L)));
                 [ #  # ]
     329         [ #  # ]:          0 :         const ::basegfx::B2DPoint aSrcPos(aSrcSize.getCenter());
     330 [ #  # ][ #  # ]:          0 :         const ::basegfx::B2DRange aDstSize(::basegfx::tools::getRange(rSmaller.getB2DPolygon(0L)));
                 [ #  # ]
     331         [ #  # ]:          0 :         const ::basegfx::B2DPoint aDstPos(aDstSize.getCenter());
     332         [ #  # ]:          0 :         aNewPoint = aNewPoint - aSrcPos + aDstPos;
     333                 :            : 
     334 [ #  # ][ #  # ]:          0 :         for(sal_uInt32 a(0L); a < aToBeCopied.count(); a++)
     335                 :            :         {
     336         [ #  # ]:          0 :             aNewPoly.append(aNewPoint);
     337                 :            :         }
     338                 :            : 
     339         [ #  # ]:          0 :         rSmaller.append(aNewPoly);
     340 [ #  # ][ #  # ]:          0 :     }
     341                 :          0 : }
     342                 :            : 
     343                 :            : //////////////////////////////////////////////////////////////////////////////
     344                 :            : // create group object with morphed polygons
     345                 :            : //
     346                 :          0 : void FuMorph::ImpInsertPolygons(
     347                 :            :     B2DPolyPolygonList_impl& rPolyPolyList3D,
     348                 :            :     sal_Bool bAttributeFade,
     349                 :            :     const SdrObject* pObj1,
     350                 :            :     const SdrObject* pObj2
     351                 :            : )
     352                 :            : {
     353                 :          0 :     Color               aStartFillCol;
     354                 :          0 :     Color               aEndFillCol;
     355                 :          0 :     Color               aStartLineCol;
     356                 :          0 :     Color               aEndLineCol;
     357                 :          0 :     long                nStartLineWidth = 0;
     358                 :          0 :     long                nEndLineWidth = 0;
     359                 :          0 :     SdrPageView*        pPageView = mpView->GetSdrPageView();
     360         [ #  # ]:          0 :     SfxItemPool*        pPool = pObj1->GetObjectItemPool();
     361         [ #  # ]:          0 :     SfxItemSet          aSet1( *pPool,SDRATTR_START,SDRATTR_NOTPERSIST_FIRST-1,EE_ITEMS_START,EE_ITEMS_END,0 );
     362         [ #  # ]:          0 :     SfxItemSet          aSet2( aSet1 );
     363                 :          0 :     sal_Bool            bLineColor = sal_False;
     364                 :          0 :     sal_Bool            bFillColor = sal_False;
     365                 :          0 :     sal_Bool            bLineWidth = sal_False;
     366                 :          0 :     sal_Bool            bIgnoreLine = sal_False;
     367                 :          0 :     sal_Bool            bIgnoreFill = sal_False;
     368                 :            : 
     369 [ #  # ][ #  # ]:          0 :     aSet1.Put(pObj1->GetMergedItemSet());
     370 [ #  # ][ #  # ]:          0 :     aSet2.Put(pObj2->GetMergedItemSet());
     371                 :            : 
     372         [ #  # ]:          0 :     const XLineStyle eLineStyle1 = ITEMVALUE( aSet1, XATTR_LINESTYLE, XLineStyleItem );
     373         [ #  # ]:          0 :     const XLineStyle eLineStyle2 = ITEMVALUE( aSet2, XATTR_LINESTYLE, XLineStyleItem );
     374         [ #  # ]:          0 :     const XFillStyle eFillStyle1 = ITEMVALUE( aSet1, XATTR_FILLSTYLE, XFillStyleItem );
     375         [ #  # ]:          0 :     const XFillStyle eFillStyle2 = ITEMVALUE( aSet2, XATTR_FILLSTYLE, XFillStyleItem );
     376                 :            : 
     377         [ #  # ]:          0 :     if ( bAttributeFade )
     378                 :            :     {
     379 [ #  # ][ #  # ]:          0 :         if ( ( eLineStyle1 != XLINE_NONE ) && ( eLineStyle2 != XLINE_NONE ) )
     380                 :            :         {
     381                 :          0 :             bLineWidth = bLineColor = sal_True;
     382                 :            : 
     383                 :            :             aStartLineCol = static_cast< XLineColorItem const & >(
     384 [ #  # ][ #  # ]:          0 :                 aSet1.Get(XATTR_LINECOLOR)).GetColorValue();
     385                 :            :             aEndLineCol = static_cast< XLineColorItem const & >(
     386 [ #  # ][ #  # ]:          0 :                 aSet2.Get(XATTR_LINECOLOR)).GetColorValue();
     387                 :            : 
     388         [ #  # ]:          0 :             nStartLineWidth = ITEMVALUE( aSet1, XATTR_LINEWIDTH, XLineWidthItem );
     389         [ #  # ]:          0 :             nEndLineWidth = ITEMVALUE( aSet2, XATTR_LINEWIDTH, XLineWidthItem );
     390                 :            :         }
     391 [ #  # ][ #  # ]:          0 :         else if ( ( eLineStyle1 == XLINE_NONE ) && ( eLineStyle2 == XLINE_NONE ) )
     392                 :          0 :             bIgnoreLine = sal_True;
     393                 :            : 
     394 [ #  # ][ #  # ]:          0 :         if ( ( eFillStyle1 == XFILL_SOLID ) && ( eFillStyle2 == XFILL_SOLID ) )
     395                 :            :         {
     396                 :          0 :             bFillColor = sal_True;
     397                 :            :             aStartFillCol = static_cast< XFillColorItem const & >(
     398 [ #  # ][ #  # ]:          0 :                 aSet1.Get(XATTR_FILLCOLOR)).GetColorValue();
     399                 :            :             aEndFillCol = static_cast< XFillColorItem const & >(
     400 [ #  # ][ #  # ]:          0 :                 aSet2.Get(XATTR_FILLCOLOR)).GetColorValue();
     401                 :            :         }
     402 [ #  # ][ #  # ]:          0 :         else if ( ( eFillStyle1 == XFILL_NONE ) && ( eFillStyle2 == XFILL_NONE ) )
     403                 :          0 :             bIgnoreFill = sal_True;
     404                 :            :     }
     405                 :            : 
     406         [ #  # ]:          0 :     if ( pPageView )
     407                 :            :     {
     408         [ #  # ]:          0 :         SfxItemSet      aSet( aSet1 );
     409 [ #  # ][ #  # ]:          0 :         SdrObjGroup*    pObjGroup = new SdrObjGroup;
     410         [ #  # ]:          0 :         SdrObjList*     pObjList = pObjGroup->GetSubList();
     411                 :          0 :         const size_t    nCount = rPolyPolyList3D.size();
     412                 :          0 :         const double    fStep = 1. / ( nCount + 1 );
     413                 :          0 :         const double    fDelta = nEndLineWidth - nStartLineWidth;
     414                 :          0 :         double          fFactor = fStep;
     415                 :            : 
     416 [ #  # ][ #  # ]:          0 :         aSet.Put( XLineStyleItem( XLINE_SOLID ) );
                 [ #  # ]
     417 [ #  # ][ #  # ]:          0 :         aSet.Put( XFillStyleItem( XFILL_SOLID ) );
                 [ #  # ]
     418                 :            : 
     419         [ #  # ]:          0 :         for ( size_t i = 0; i < nCount; i++, fFactor += fStep )
     420                 :            :         {
     421         [ #  # ]:          0 :             const ::basegfx::B2DPolyPolygon& rPolyPoly3D = *rPolyPolyList3D[ i ];
     422 [ #  # ][ #  # ]:          0 :             SdrPathObj* pNewObj = new SdrPathObj(OBJ_POLY, rPolyPoly3D);
     423                 :            : 
     424                 :            :             // Linienfarbe
     425         [ #  # ]:          0 :             if ( bLineColor )
     426                 :            :             {
     427                 :          0 :                 const basegfx::BColor aLineColor(basegfx::interpolate(aStartLineCol.getBColor(), aEndLineCol.getBColor(), fFactor));
     428 [ #  # ][ #  # ]:          0 :                 aSet.Put( XLineColorItem( aEmptyStr, Color(aLineColor)));
                 [ #  # ]
     429                 :            :             }
     430         [ #  # ]:          0 :             else if ( bIgnoreLine )
     431 [ #  # ][ #  # ]:          0 :                 aSet.Put( XLineStyleItem( XLINE_NONE ) );
                 [ #  # ]
     432                 :            : 
     433                 :            :             // Fuellfarbe
     434         [ #  # ]:          0 :             if ( bFillColor )
     435                 :            :             {
     436                 :          0 :                 const basegfx::BColor aFillColor(basegfx::interpolate(aStartFillCol.getBColor(), aEndFillCol.getBColor(), fFactor));
     437 [ #  # ][ #  # ]:          0 :                 aSet.Put( XFillColorItem( aEmptyStr, Color(aFillColor)));
                 [ #  # ]
     438                 :            :             }
     439         [ #  # ]:          0 :             else if ( bIgnoreFill )
     440 [ #  # ][ #  # ]:          0 :                 aSet.Put( XFillStyleItem( XFILL_NONE ) );
                 [ #  # ]
     441                 :            : 
     442                 :            :             // Linienstaerke
     443         [ #  # ]:          0 :             if ( bLineWidth )
     444 [ #  # ][ #  # ]:          0 :                 aSet.Put( XLineWidthItem( nStartLineWidth + (long) ( fFactor * fDelta + 0.5 ) ) );
                 [ #  # ]
     445                 :            : 
     446         [ #  # ]:          0 :             pNewObj->SetMergedItemSetAndBroadcast(aSet);
     447                 :            : 
     448         [ #  # ]:          0 :             pObjList->InsertObject( pNewObj, LIST_APPEND );
     449                 :            :         }
     450                 :            : 
     451         [ #  # ]:          0 :         if ( nCount )
     452                 :            :         {
     453 [ #  # ][ #  # ]:          0 :             pObjList->InsertObject( pObj1->Clone(), 0 );
     454 [ #  # ][ #  # ]:          0 :             pObjList->InsertObject( pObj2->Clone(), LIST_APPEND );
     455         [ #  # ]:          0 :             mpView->DeleteMarked();
     456         [ #  # ]:          0 :             mpView->InsertObjectAtView( pObjGroup, *pPageView, SDRINSERT_SETDEFLAYER );
     457         [ #  # ]:          0 :         }
     458 [ #  # ][ #  # ]:          0 :     }
     459                 :          0 : }
     460                 :            : 
     461                 :            : //////////////////////////////////////////////////////////////////////////////
     462                 :            : // create single morphed PolyPolygon
     463                 :            : //
     464                 :          0 : ::basegfx::B2DPolyPolygon* FuMorph::ImpCreateMorphedPolygon(
     465                 :            :     const ::basegfx::B2DPolyPolygon& rPolyPolyStart,
     466                 :            :     const ::basegfx::B2DPolyPolygon& rPolyPolyEnd,
     467                 :            :     double fMorphingFactor
     468                 :            : )
     469                 :            : {
     470         [ #  # ]:          0 :     ::basegfx::B2DPolyPolygon* pNewPolyPolygon = new ::basegfx::B2DPolyPolygon();
     471                 :          0 :     const double fFactor = 1.0 - fMorphingFactor;
     472                 :            : 
     473         [ #  # ]:          0 :     for(sal_uInt32 a(0L); a < rPolyPolyStart.count(); a++)
     474                 :            :     {
     475         [ #  # ]:          0 :         const ::basegfx::B2DPolygon aPolyStart(rPolyPolyStart.getB2DPolygon(a));
     476         [ #  # ]:          0 :         const ::basegfx::B2DPolygon aPolyEnd(rPolyPolyEnd.getB2DPolygon(a));
     477         [ #  # ]:          0 :         const sal_uInt32 nCount(aPolyStart.count());
     478         [ #  # ]:          0 :         ::basegfx::B2DPolygon aNewPolygon;
     479                 :            : 
     480         [ #  # ]:          0 :         for(sal_uInt32 b(0L); b < nCount; b++)
     481                 :            :         {
     482         [ #  # ]:          0 :             const ::basegfx::B2DPoint& aPtStart(aPolyStart.getB2DPoint(b));
     483         [ #  # ]:          0 :             const ::basegfx::B2DPoint& aPtEnd(aPolyEnd.getB2DPoint(b));
     484         [ #  # ]:          0 :             aNewPolygon.append(aPtEnd + ((aPtStart - aPtEnd) * fFactor));
     485                 :          0 :         }
     486                 :            : 
     487 [ #  # ][ #  # ]:          0 :         aNewPolygon.setClosed(aPolyStart.isClosed() && aPolyEnd.isClosed());
         [ #  # ][ #  # ]
                 [ #  # ]
     488         [ #  # ]:          0 :         pNewPolyPolygon->append(aNewPolygon);
     489 [ #  # ][ #  # ]:          0 :     }
                 [ #  # ]
     490                 :            : 
     491                 :          0 :     return pNewPolyPolygon;
     492                 :            : }
     493                 :            : 
     494                 :            : //////////////////////////////////////////////////////////////////////////////
     495                 :            : // create morphed PolyPolygons
     496                 :            : //
     497                 :          0 : sal_Bool FuMorph::ImpMorphPolygons(
     498                 :            :     const ::basegfx::B2DPolyPolygon& rPolyPoly1,
     499                 :            :     const ::basegfx::B2DPolyPolygon& rPolyPoly2,
     500                 :            :     const sal_uInt16 nSteps,
     501                 :            :     B2DPolyPolygonList_impl& rPolyPolyList3D
     502                 :            : )
     503                 :            : {
     504         [ #  # ]:          0 :     if(nSteps)
     505                 :            :     {
     506         [ #  # ]:          0 :         const ::basegfx::B2DRange aStartPolySize(::basegfx::tools::getRange(rPolyPoly1));
     507         [ #  # ]:          0 :         const ::basegfx::B2DPoint aStartCenter(aStartPolySize.getCenter());
     508         [ #  # ]:          0 :         const ::basegfx::B2DRange aEndPolySize(::basegfx::tools::getRange(rPolyPoly2));
     509         [ #  # ]:          0 :         const ::basegfx::B2DPoint aEndCenter(aEndPolySize.getCenter());
     510                 :          0 :         const ::basegfx::B2DPoint aDelta(aEndCenter - aStartCenter);
     511                 :          0 :         const double fFactor(1.0 / (nSteps + 1));
     512                 :          0 :         double fValue(0.0);
     513                 :            : 
     514         [ #  # ]:          0 :         for(sal_uInt16 i(0); i < nSteps; i++)
     515                 :            :         {
     516                 :          0 :             fValue += fFactor;
     517         [ #  # ]:          0 :             ::basegfx::B2DPolyPolygon* pNewPolyPoly2D = ImpCreateMorphedPolygon(rPolyPoly1, rPolyPoly2, fValue);
     518                 :            : 
     519         [ #  # ]:          0 :             const ::basegfx::B2DRange aNewPolySize(::basegfx::tools::getRange(*pNewPolyPoly2D));
     520         [ #  # ]:          0 :             const ::basegfx::B2DPoint aNewS(aNewPolySize.getCenter());
     521                 :          0 :             const ::basegfx::B2DPoint aRealS(aStartCenter + (aDelta * fValue));
     522                 :          0 :             const ::basegfx::B2DPoint aDiff(aRealS - aNewS);
     523                 :            : 
     524 [ #  # ][ #  # ]:          0 :             pNewPolyPoly2D->transform(basegfx::tools::createTranslateB2DHomMatrix(aDiff));
                 [ #  # ]
     525         [ #  # ]:          0 :             rPolyPolyList3D.push_back( pNewPolyPoly2D );
     526                 :          0 :         }
     527                 :            :     }
     528                 :          0 :     return sal_True;
     529                 :            : }
     530                 :            : 
     531                 :            : } // end of namespace sd
     532                 :            : 
     533                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10