LCOV - code coverage report
Current view: top level - svx/source/svdraw - svdocirc.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 226 657 34.4 %
Date: 2015-06-13 12:38:46 Functions: 31 57 54.4 %
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 <basegfx/matrix/b2dhommatrix.hxx>
      21             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      22             : #include <basegfx/point/b2dpoint.hxx>
      23             : #include <basegfx/polygon/b2dpolygon.hxx>
      24             : #include <basegfx/polygon/b2dpolygontools.hxx>
      25             : #include <editeng/eeitem.hxx>
      26             : #include <math.h>
      27             : #include <svl/style.hxx>
      28             : 
      29             : #include "svdglob.hxx"
      30             : #include "svx/svdstr.hrc"
      31             : 
      32             : #include <sdr/contact/viewcontactofsdrcircobj.hxx>
      33             : #include <sdr/properties/circleproperties.hxx>
      34             : #include <svx/svdattr.hxx>
      35             : #include <svx/svddrag.hxx>
      36             : #include <svx/svdetc.hxx>
      37             : #include <svx/svdmodel.hxx>
      38             : #include <svx/svdocirc.hxx>
      39             : #include <svx/svdopath.hxx>
      40             : #include <svx/svdpage.hxx>
      41             : #include <svx/svdpool.hxx>
      42             : #include <svx/svdtrans.hxx>
      43             : #include <svx/svdview.hxx>
      44             : #include <svx/sxciaitm.hxx>
      45             : #include <sxcikitm.hxx>
      46             : #include <svx/xlnedit.hxx>
      47             : #include <svx/xlnedwit.hxx>
      48             : #include <svx/xlnstit.hxx>
      49             : #include <svx/xlnstwit.hxx>
      50             : #include <svx/xlnwtit.hxx>
      51             : #include <svx/xpool.hxx>
      52             : 
      53             : using namespace com::sun::star;
      54             : 
      55           0 : Point GetAnglePnt(const Rectangle& rR, long nAngle)
      56             : {
      57           0 :     Point aCenter(rR.Center());
      58           0 :     long nWdt=rR.Right()-rR.Left();
      59           0 :     long nHgt=rR.Bottom()-rR.Top();
      60           0 :     long nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
      61             :     double a;
      62           0 :     a=nAngle*nPi180;
      63           0 :     Point aRetval(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
      64           0 :     if (nWdt==0) aRetval.X()=0;
      65           0 :     if (nHgt==0) aRetval.Y()=0;
      66           0 :     if (nWdt!=nHgt) {
      67           0 :         if (nWdt>nHgt) {
      68           0 :             if (nWdt!=0) {
      69             :                 // stop possible overruns for very large objects
      70           0 :                 if (std::abs(nHgt)>32767 || std::abs(aRetval.Y())>32767) {
      71           0 :                     aRetval.Y()=BigMulDiv(aRetval.Y(),nHgt,nWdt);
      72             :                 } else {
      73           0 :                     aRetval.Y()=aRetval.Y()*nHgt/nWdt;
      74             :                 }
      75             :             }
      76             :         } else {
      77           0 :             if (nHgt!=0) {
      78             :                 // stop possible overruns for very large objects
      79           0 :                 if (std::abs(nWdt)>32767 || std::abs(aRetval.X())>32767) {
      80           0 :                     aRetval.X()=BigMulDiv(aRetval.X(),nWdt,nHgt);
      81             :                 } else {
      82           0 :                     aRetval.X()=aRetval.X()*nWdt/nHgt;
      83             :                 }
      84             :             }
      85             :         }
      86             :     }
      87           0 :     aRetval+=aCenter;
      88           0 :     return aRetval;
      89             : }
      90             : 
      91             : 
      92             : // BaseProperties section
      93             : 
      94         115 : sdr::properties::BaseProperties* SdrCircObj::CreateObjectSpecificProperties()
      95             : {
      96         115 :     return new sdr::properties::CircleProperties(*this);
      97             : }
      98             : 
      99             : 
     100             : // DrawContact section
     101             : 
     102         116 : sdr::contact::ViewContact* SdrCircObj::CreateObjectSpecificViewContact()
     103             : {
     104         116 :     return new sdr::contact::ViewContactOfSdrCircObj(*this);
     105             : }
     106             : 
     107             : 
     108             : 
     109       10304 : TYPEINIT1(SdrCircObj,SdrRectObj);
     110             : 
     111           1 : SdrCircObj::SdrCircObj(SdrObjKind eNewKind)
     112             : {
     113           1 :     nStartAngle=0;
     114           1 :     nEndAngle=36000;
     115           1 :     meCircleKind=eNewKind;
     116           1 :     bClosedObj=eNewKind!=OBJ_CARC;
     117           1 : }
     118             : 
     119         115 : SdrCircObj::SdrCircObj(SdrObjKind eNewKind, const Rectangle& rRect):
     120         115 :     SdrRectObj(rRect)
     121             : {
     122         115 :     nStartAngle=0;
     123         115 :     nEndAngle=36000;
     124         115 :     meCircleKind=eNewKind;
     125         115 :     bClosedObj=eNewKind!=OBJ_CARC;
     126         115 : }
     127             : 
     128           0 : SdrCircObj::SdrCircObj(SdrObjKind eNewKind, const Rectangle& rRect, long nNewStartWink, long nNewEndWink):
     129           0 :     SdrRectObj(rRect)
     130             : {
     131           0 :     long nAngleDif=nNewEndWink-nNewStartWink;
     132           0 :     nStartAngle=NormAngle360(nNewStartWink);
     133           0 :     nEndAngle=NormAngle360(nNewEndWink);
     134           0 :     if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
     135           0 :     meCircleKind=eNewKind;
     136           0 :     bClosedObj=eNewKind!=OBJ_CARC;
     137           0 : }
     138             : 
     139         232 : SdrCircObj::~SdrCircObj()
     140             : {
     141         232 : }
     142             : 
     143           0 : void SdrCircObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
     144             : {
     145           0 :     bool bCanConv=!HasText() || ImpCanConvTextToCurve();
     146           0 :     rInfo.bEdgeRadiusAllowed    = false;
     147           0 :     rInfo.bCanConvToPath=bCanConv;
     148           0 :     rInfo.bCanConvToPoly=bCanConv;
     149           0 :     rInfo.bCanConvToContour = !IsFontwork() && (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
     150           0 : }
     151             : 
     152        2026 : sal_uInt16 SdrCircObj::GetObjIdentifier() const
     153             : {
     154        2026 :     return sal_uInt16(meCircleKind);
     155             : }
     156             : 
     157         149 : bool SdrCircObj::PaintNeedsXPolyCirc() const
     158             : {
     159             :     // XPoly is necessary for all rotated ellipse objects, circle and
     160             :     // ellipse segments.
     161             :     // If not WIN, then (for now) also for circle/ellipse segments and circle/
     162             :     // ellipse arcs (for precision)
     163         149 :     bool bNeed=aGeo.nRotationAngle!=0 || aGeo.nShearAngle!=0 || meCircleKind==OBJ_CCUT;
     164             :     // If not WIN, then for everything except full circle (for now!)
     165         149 :     if (meCircleKind!=OBJ_CIRC) bNeed = true;
     166             : 
     167         149 :     const SfxItemSet& rSet = GetObjectItemSet();
     168         149 :     if(!bNeed)
     169             :     {
     170             :         // XPoly is necessary for everything that isn't LineSolid or LineNone
     171          98 :         drawing::LineStyle eLine = static_cast<const XLineStyleItem&>(rSet.Get(XATTR_LINESTYLE)).GetValue();
     172          98 :         bNeed = eLine != drawing::LineStyle_NONE && eLine != drawing::LineStyle_SOLID;
     173             : 
     174             :         // XPoly is necessary for thick lines
     175          98 :         if(!bNeed && eLine != drawing::LineStyle_NONE)
     176          85 :             bNeed = static_cast<const XLineWidthItem&>(rSet.Get(XATTR_LINEWIDTH)).GetValue() != 0;
     177             : 
     178             :         // XPoly is necessary for circle arcs with line ends
     179          98 :         if(!bNeed && meCircleKind == OBJ_CARC)
     180             :         {
     181             :             // start of the line is here if StartPolygon, StartWidth!=0
     182           0 :             bNeed=static_cast<const XLineStartItem&>(rSet.Get(XATTR_LINESTART)).GetLineStartValue().count() != 0L &&
     183           0 :                   static_cast<const XLineStartWidthItem&>(rSet.Get(XATTR_LINESTARTWIDTH)).GetValue() != 0;
     184             : 
     185           0 :             if(!bNeed)
     186             :             {
     187             :                 // end of the line is here if EndPolygon, EndWidth!=0
     188           0 :                 bNeed = static_cast<const XLineEndItem&>(rSet.Get(XATTR_LINEEND)).GetLineEndValue().count() != 0L &&
     189           0 :                         static_cast<const XLineEndWidthItem&>(rSet.Get(XATTR_LINEENDWIDTH)).GetValue() != 0;
     190             :             }
     191             :         }
     192             :     }
     193             : 
     194             :     // XPoly is necessary if Fill !=None and !=Solid
     195         149 :     if(!bNeed && meCircleKind != OBJ_CARC)
     196             :     {
     197          87 :         drawing::FillStyle eFill=static_cast<const XFillStyleItem&>(rSet.Get(XATTR_FILLSTYLE)).GetValue();
     198          87 :         bNeed = eFill != drawing::FillStyle_NONE && eFill != drawing::FillStyle_SOLID;
     199             :     }
     200             : 
     201         149 :     if(!bNeed && meCircleKind != OBJ_CIRC && nStartAngle == nEndAngle)
     202           0 :         bNeed = true; // otherwise we're drawing a full circle
     203             : 
     204         149 :     return bNeed;
     205             : }
     206             : 
     207          68 : basegfx::B2DPolygon SdrCircObj::ImpCalcXPolyCirc(const SdrObjKind eCicrleKind, const Rectangle& rRect1, long nStart, long nEnd) const
     208             : {
     209          68 :     const basegfx::B2DRange aRange(rRect1.Left(), rRect1.Top(), rRect1.Right(), rRect1.Bottom());
     210          68 :     basegfx::B2DPolygon aCircPolygon;
     211             : 
     212          68 :     if(OBJ_CIRC == eCicrleKind)
     213             :     {
     214             :         // create full circle. Do not use createPolygonFromEllipse; it's necessary
     215             :         // to get the start point to the bottom of the circle to keep compatible to
     216             :         // old geometry creation
     217          17 :         aCircPolygon = basegfx::tools::createPolygonFromUnitCircle(1);
     218             : 
     219             :         // needs own scaling and translation from unit circle to target size (same as
     220             :         // would be in createPolygonFromEllipse)
     221          17 :         const basegfx::B2DPoint aCenter(aRange.getCenter());
     222             :         const basegfx::B2DHomMatrix aMatrix(basegfx::tools::createScaleTranslateB2DHomMatrix(
     223          34 :             aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
     224          68 :             aCenter.getX(), aCenter.getY()));
     225          34 :         aCircPolygon.transform(aMatrix);
     226             :     }
     227             :     else
     228             :     {
     229             :         // mirror start, end for geometry creation since model coordinate system is mirrored in Y
     230             :         // #i111715# increase numerical correctness by first dividing and not using F_PI1800
     231          51 :         const double fStart((((36000 - nEnd) % 36000) / 18000.0) * F_PI);
     232          51 :         const double fEnd((((36000 - nStart) % 36000) / 18000.0) * F_PI);
     233             : 
     234             :         // create circle segment. This is not closed by default
     235         153 :         aCircPolygon = basegfx::tools::createPolygonFromEllipseSegment(
     236         102 :             aRange.getCenter(), aRange.getWidth() / 2.0, aRange.getHeight() / 2.0,
     237          51 :             fStart, fEnd);
     238             : 
     239             :         // check closing states
     240          51 :         const bool bCloseSegment(OBJ_CARC != eCicrleKind);
     241          51 :         const bool bCloseUsingCenter(OBJ_SECT == eCicrleKind);
     242             : 
     243          51 :         if(bCloseSegment)
     244             :         {
     245          39 :             if(bCloseUsingCenter)
     246             :             {
     247             :                 // add center point at start (for historical reasons)
     248          12 :                 basegfx::B2DPolygon aSector;
     249          12 :                 aSector.append(aRange.getCenter());
     250          12 :                 aSector.append(aCircPolygon);
     251          12 :                 aCircPolygon = aSector;
     252             :             }
     253             : 
     254             :             // close
     255          39 :             aCircPolygon.setClosed(true);
     256             :         }
     257             :     }
     258             : 
     259             :     // #i76950#
     260          68 :     if(aGeo.nShearAngle || aGeo.nRotationAngle)
     261             :     {
     262             :         // translate top left to (0,0)
     263           0 :         const basegfx::B2DPoint aTopLeft(aRange.getMinimum());
     264             :         basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
     265           0 :             -aTopLeft.getX(), -aTopLeft.getY()));
     266             : 
     267             :         // shear, rotate and back to top left (if needed)
     268             :         aMatrix = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(
     269           0 :             aGeo.nShearAngle ? tan((36000 - aGeo.nShearAngle) * F_PI18000) : 0.0,
     270           0 :             aGeo.nRotationAngle ? (36000 - aGeo.nRotationAngle) * F_PI18000 : 0.0,
     271           0 :             aTopLeft) * aMatrix;
     272             : 
     273             :         // apply transformation
     274           0 :         aCircPolygon.transform(aMatrix);
     275             :     }
     276             : 
     277          68 :     return aCircPolygon;
     278             : }
     279             : 
     280          65 : void SdrCircObj::RecalcXPoly()
     281             : {
     282          65 :     const basegfx::B2DPolygon aPolyCirc(ImpCalcXPolyCirc(meCircleKind, maRect, nStartAngle, nEndAngle));
     283          65 :     mpXPoly = new XPolygon(aPolyCirc);
     284          65 : }
     285             : 
     286           2 : OUString SdrCircObj::TakeObjNameSingul() const
     287             : {
     288           2 :     sal_uInt16 nID=STR_ObjNameSingulCIRC;
     289           2 :     if (maRect.GetWidth() == maRect.GetHeight() && aGeo.nShearAngle==0)
     290             :     {
     291           1 :         switch (meCircleKind) {
     292           1 :             case OBJ_CIRC: nID=STR_ObjNameSingulCIRC; break;
     293           0 :             case OBJ_SECT: nID=STR_ObjNameSingulSECT; break;
     294           0 :             case OBJ_CARC: nID=STR_ObjNameSingulCARC; break;
     295           0 :             case OBJ_CCUT: nID=STR_ObjNameSingulCCUT; break;
     296           0 :             default: break;
     297             :         }
     298             :     } else {
     299           1 :         switch (meCircleKind) {
     300           1 :             case OBJ_CIRC: nID=STR_ObjNameSingulCIRCE; break;
     301           0 :             case OBJ_SECT: nID=STR_ObjNameSingulSECTE; break;
     302           0 :             case OBJ_CARC: nID=STR_ObjNameSingulCARCE; break;
     303           0 :             case OBJ_CCUT: nID=STR_ObjNameSingulCCUTE; break;
     304           0 :             default: break;
     305             :         }
     306             :     }
     307           2 :     OUStringBuffer sName(ImpGetResStr(nID));
     308             : 
     309           4 :     OUString aName(GetName());
     310           2 :     if (!aName.isEmpty())
     311             :     {
     312           0 :         sName.append(' ');
     313           0 :         sName.append('\'');
     314           0 :         sName.append(aName);
     315           0 :         sName.append('\'');
     316             :     }
     317           4 :     return sName.makeStringAndClear();
     318             : }
     319             : 
     320          20 : OUString SdrCircObj::TakeObjNamePlural() const
     321             : {
     322          20 :     sal_uInt16 nID=STR_ObjNamePluralCIRC;
     323          20 :     if (maRect.GetWidth() == maRect.GetHeight() && aGeo.nShearAngle==0)
     324             :     {
     325          14 :         switch (meCircleKind) {
     326           2 :             case OBJ_CIRC: nID=STR_ObjNamePluralCIRC; break;
     327           0 :             case OBJ_SECT: nID=STR_ObjNamePluralSECT; break;
     328          12 :             case OBJ_CARC: nID=STR_ObjNamePluralCARC; break;
     329           0 :             case OBJ_CCUT: nID=STR_ObjNamePluralCCUT; break;
     330           0 :             default: break;
     331             :         }
     332             :     } else {
     333           6 :         switch (meCircleKind) {
     334           6 :             case OBJ_CIRC: nID=STR_ObjNamePluralCIRCE; break;
     335           0 :             case OBJ_SECT: nID=STR_ObjNamePluralSECTE; break;
     336           0 :             case OBJ_CARC: nID=STR_ObjNamePluralCARCE; break;
     337           0 :             case OBJ_CCUT: nID=STR_ObjNamePluralCCUTE; break;
     338           0 :             default: break;
     339             :         }
     340             :     }
     341          20 :     return ImpGetResStr(nID);
     342             : }
     343             : 
     344           1 : SdrCircObj* SdrCircObj::Clone() const
     345             : {
     346           1 :     return CloneHelper< SdrCircObj >();
     347             : }
     348             : 
     349           0 : basegfx::B2DPolyPolygon SdrCircObj::TakeXorPoly() const
     350             : {
     351           0 :     const basegfx::B2DPolygon aCircPolygon(ImpCalcXPolyCirc(meCircleKind, maRect, nStartAngle, nEndAngle));
     352           0 :     return basegfx::B2DPolyPolygon(aCircPolygon);
     353             : }
     354             : 
     355             : struct ImpCircUser : public SdrDragStatUserData
     356             : {
     357             :     Rectangle                   aR;
     358             :     Point                       aCenter;
     359             :     Point                       aRadius;
     360             :     Point                       aP1;
     361             :     Point                       aP2;
     362             :     long                        nMaxRad;
     363             :     long                        nHgt;
     364             :     long                        nWdt;
     365             :     long                        nStart;
     366             :     long                        nEnd;
     367             :     long                        nAngle;
     368             :     bool                        bRight; // not yet implemented
     369             : 
     370             : public:
     371           0 :     ImpCircUser()
     372             :     :   nMaxRad(0),
     373             :         nHgt(0),
     374             :         nWdt(0),
     375             :         nStart(0),
     376             :         nEnd(0),
     377             :         nAngle(0),
     378           0 :         bRight(false)
     379           0 :     {}
     380             :     void SetCreateParams(SdrDragStat& rStat);
     381             : };
     382             : 
     383          12 : sal_uInt32 SdrCircObj::GetHdlCount() const
     384             : {
     385          12 :     if(OBJ_CIRC != meCircleKind)
     386             :     {
     387           0 :         return 10L;
     388             :     }
     389             :     else
     390             :     {
     391          12 :         return 8L;
     392             :     }
     393             : }
     394             : 
     395          96 : SdrHdl* SdrCircObj::GetHdl(sal_uInt32 nHdlNum) const
     396             : {
     397          96 :     if (meCircleKind==OBJ_CIRC)
     398             :     {
     399          96 :         nHdlNum += 2L;
     400             :     }
     401             : 
     402          96 :     SdrHdl* pH = NULL;
     403          96 :     Point aPnt;
     404          96 :     SdrHdlKind eLocalKind(HDL_MOVE);
     405          96 :     sal_uInt32 nPNum(0);
     406             : 
     407          96 :     switch (nHdlNum)
     408             :     {
     409             :         case 0:
     410           0 :             aPnt = GetAnglePnt(maRect,nStartAngle);
     411           0 :             eLocalKind = HDL_CIRC;
     412           0 :             nPNum = 1;
     413           0 :             break;
     414             :         case 1:
     415           0 :             aPnt = GetAnglePnt(maRect,nEndAngle);
     416           0 :             eLocalKind = HDL_CIRC;
     417           0 :             nPNum = 2L;
     418           0 :             break;
     419             :         case 2:
     420          12 :             aPnt = maRect.TopLeft();
     421          12 :             eLocalKind = HDL_UPLFT;
     422          12 :             break;
     423             :         case 3:
     424          12 :             aPnt = maRect.TopCenter();
     425          12 :             eLocalKind = HDL_UPPER;
     426          12 :             break;
     427             :         case 4:
     428          12 :             aPnt = maRect.TopRight();
     429          12 :             eLocalKind = HDL_UPRGT;
     430          12 :             break;
     431             :         case 5:
     432          12 :             aPnt = maRect.LeftCenter();
     433          12 :             eLocalKind = HDL_LEFT;
     434          12 :             break;
     435             :         case 6:
     436          12 :             aPnt = maRect.RightCenter();
     437          12 :             eLocalKind = HDL_RIGHT;
     438          12 :             break;
     439             :         case 7:
     440          12 :             aPnt = maRect.BottomLeft();
     441          12 :             eLocalKind = HDL_LWLFT;
     442          12 :             break;
     443             :         case 8:
     444          12 :             aPnt = maRect.BottomCenter();
     445          12 :             eLocalKind = HDL_LOWER;
     446          12 :             break;
     447             :         case 9:
     448          12 :             aPnt = maRect.BottomRight();
     449          12 :             eLocalKind = HDL_LWRGT;
     450          12 :             break;
     451             :     }
     452             : 
     453          96 :     if (aGeo.nShearAngle)
     454             :     {
     455           0 :         ShearPoint(aPnt,maRect.TopLeft(),aGeo.nTan);
     456             :     }
     457             : 
     458          96 :     if (aGeo.nRotationAngle)
     459             :     {
     460           0 :         RotatePoint(aPnt,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
     461             :     }
     462             : 
     463          96 :     if (eLocalKind != HDL_MOVE)
     464             :     {
     465          96 :         pH = new SdrHdl(aPnt,eLocalKind);
     466          96 :         pH->SetPointNum(nPNum);
     467          96 :         pH->SetObj(const_cast<SdrCircObj*>(this));
     468          96 :         pH->SetRotationAngle(aGeo.nRotationAngle);
     469             :     }
     470             : 
     471          96 :     return pH;
     472             : }
     473             : 
     474             : 
     475             : 
     476          15 : bool SdrCircObj::hasSpecialDrag() const
     477             : {
     478          15 :     return true;
     479             : }
     480             : 
     481           0 : bool SdrCircObj::beginSpecialDrag(SdrDragStat& rDrag) const
     482             : {
     483           0 :     const bool bAngle(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
     484             : 
     485           0 :     if(bAngle)
     486             :     {
     487           0 :         if(1 == rDrag.GetHdl()->GetPointNum() || 2 == rDrag.GetHdl()->GetPointNum())
     488             :         {
     489           0 :             rDrag.SetNoSnap(true);
     490             :         }
     491             : 
     492           0 :         return true;
     493             :     }
     494             : 
     495           0 :     return SdrTextObj::beginSpecialDrag(rDrag);
     496             : }
     497             : 
     498           0 : bool SdrCircObj::applySpecialDrag(SdrDragStat& rDrag)
     499             : {
     500           0 :     const bool bAngle(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
     501             : 
     502           0 :     if(bAngle)
     503             :     {
     504           0 :         Point aPt(rDrag.GetNow());
     505             : 
     506           0 :         if (aGeo.nRotationAngle!=0)
     507           0 :             RotatePoint(aPt,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos);
     508             : 
     509           0 :         if (aGeo.nShearAngle!=0)
     510           0 :             ShearPoint(aPt,maRect.TopLeft(),-aGeo.nTan);
     511             : 
     512           0 :         aPt -= maRect.Center();
     513             : 
     514           0 :         long nWdt = maRect.Right() - maRect.Left();
     515           0 :         long nHgt = maRect.Bottom() - maRect.Top();
     516             : 
     517           0 :         if(nWdt>=nHgt)
     518             :         {
     519           0 :             aPt.Y()=BigMulDiv(aPt.Y(),nWdt,nHgt);
     520             :         }
     521             :         else
     522             :         {
     523           0 :             aPt.X()=BigMulDiv(aPt.X(),nHgt,nWdt);
     524             :         }
     525             : 
     526           0 :         long nAngle=NormAngle360(GetAngle(aPt));
     527             : 
     528           0 :         if (rDrag.GetView() && rDrag.GetView()->IsAngleSnapEnabled())
     529             :         {
     530           0 :             long nSA=rDrag.GetView()->GetSnapAngle();
     531             : 
     532           0 :             if (nSA!=0)
     533             :             {
     534           0 :                 nAngle+=nSA/2;
     535           0 :                 nAngle/=nSA;
     536           0 :                 nAngle*=nSA;
     537           0 :                 nAngle=NormAngle360(nAngle);
     538             :             }
     539             :         }
     540             : 
     541           0 :         if(1 == rDrag.GetHdl()->GetPointNum())
     542             :         {
     543           0 :             nStartAngle = nAngle;
     544             :         }
     545           0 :         else if(2 == rDrag.GetHdl()->GetPointNum())
     546             :         {
     547           0 :             nEndAngle = nAngle;
     548             :         }
     549             : 
     550           0 :         SetRectsDirty();
     551           0 :         SetXPolyDirty();
     552           0 :         ImpSetCircInfoToAttr();
     553           0 :         SetChanged();
     554             : 
     555           0 :         return true;
     556             :     }
     557             :     else
     558             :     {
     559           0 :         return SdrTextObj::applySpecialDrag(rDrag);
     560             :     }
     561             : }
     562             : 
     563           0 : OUString SdrCircObj::getSpecialDragComment(const SdrDragStat& rDrag) const
     564             : {
     565           0 :     const bool bCreateComment(rDrag.GetView() && this == rDrag.GetView()->GetCreateObj());
     566             : 
     567           0 :     if(bCreateComment)
     568             :     {
     569           0 :         OUString aStr;
     570           0 :         ImpTakeDescriptionStr(STR_ViewCreateObj, aStr);
     571           0 :         OUStringBuffer aBuf(aStr);
     572           0 :         const sal_uInt32 nPointCount(rDrag.GetPointAnz());
     573             : 
     574           0 :         if(OBJ_CIRC != meCircleKind && nPointCount > 2)
     575             :         {
     576           0 :             const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
     577             :             sal_Int32 nAngle;
     578             : 
     579           0 :             aBuf.appendAscii(" (");
     580             : 
     581           0 :             if(3 == nPointCount)
     582             :             {
     583           0 :                 nAngle = pU->nStart;
     584             :             }
     585             :             else
     586             :             {
     587           0 :                 nAngle = pU->nEnd;
     588             :             }
     589             : 
     590           0 :             aBuf.append(GetAngleStr(nAngle,false));
     591           0 :             aBuf.append(')');
     592             :         }
     593             : 
     594           0 :         return aBuf.makeStringAndClear();
     595             :     }
     596             :     else
     597             :     {
     598           0 :         const bool bAngle(rDrag.GetHdl() && HDL_CIRC == rDrag.GetHdl()->GetKind());
     599             : 
     600           0 :         if(bAngle)
     601             :         {
     602           0 :             const sal_Int32 nAngle(1 == rDrag.GetHdl()->GetPointNum() ? nStartAngle : nEndAngle);
     603             : 
     604           0 :             OUString aStr;
     605           0 :             ImpTakeDescriptionStr(STR_DragCircAngle, aStr);
     606           0 :             OUStringBuffer aBuf(aStr);
     607           0 :             aBuf.appendAscii(" (");
     608           0 :             aBuf.append(GetAngleStr(nAngle,false));
     609           0 :             aBuf.append(')');
     610             : 
     611           0 :             return aBuf.makeStringAndClear();
     612             :         }
     613             :         else
     614             :         {
     615           0 :             return SdrTextObj::getSpecialDragComment(rDrag);
     616             :         }
     617             :     }
     618             : }
     619             : 
     620             : 
     621             : 
     622           0 : void ImpCircUser::SetCreateParams(SdrDragStat& rStat)
     623             : {
     624           0 :     rStat.TakeCreateRect(aR);
     625           0 :     aR.Justify();
     626           0 :     aCenter=aR.Center();
     627           0 :     nWdt=aR.Right()-aR.Left();
     628           0 :     nHgt=aR.Bottom()-aR.Top();
     629           0 :     nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
     630           0 :     nStart=0;
     631           0 :     nEnd=36000;
     632           0 :     if (rStat.GetPointAnz()>2) {
     633           0 :         Point aP(rStat.GetPoint(2)-aCenter);
     634           0 :         if (nWdt==0) aP.X()=0;
     635           0 :         if (nHgt==0) aP.Y()=0;
     636           0 :         if (nWdt>=nHgt) {
     637           0 :             if (nHgt!=0) aP.Y()=aP.Y()*nWdt/nHgt;
     638             :         } else {
     639           0 :             if (nWdt!=0) aP.X()=aP.X()*nHgt/nWdt;
     640             :         }
     641           0 :         nStart=NormAngle360(GetAngle(aP));
     642           0 :         if (rStat.GetView()!=NULL && rStat.GetView()->IsAngleSnapEnabled()) {
     643           0 :             long nSA=rStat.GetView()->GetSnapAngle();
     644           0 :             if (nSA!=0) { // angle snapping
     645           0 :                 nStart+=nSA/2;
     646           0 :                 nStart/=nSA;
     647           0 :                 nStart*=nSA;
     648           0 :                 nStart=NormAngle360(nStart);
     649             :             }
     650             :         }
     651           0 :         aP1 = GetAnglePnt(aR,nStart);
     652           0 :         nEnd=nStart;
     653           0 :         aP2=aP1;
     654           0 :     } else aP1=aCenter;
     655           0 :     if (rStat.GetPointAnz()>3) {
     656           0 :         Point aP(rStat.GetPoint(3)-aCenter);
     657           0 :         if (nWdt>=nHgt) {
     658           0 :             aP.Y()=BigMulDiv(aP.Y(),nWdt,nHgt);
     659             :         } else {
     660           0 :             aP.X()=BigMulDiv(aP.X(),nHgt,nWdt);
     661             :         }
     662           0 :         nEnd=NormAngle360(GetAngle(aP));
     663           0 :         if (rStat.GetView()!=NULL && rStat.GetView()->IsAngleSnapEnabled()) {
     664           0 :             long nSA=rStat.GetView()->GetSnapAngle();
     665           0 :             if (nSA!=0) { // angle snapping
     666           0 :                 nEnd+=nSA/2;
     667           0 :                 nEnd/=nSA;
     668           0 :                 nEnd*=nSA;
     669           0 :                 nEnd=NormAngle360(nEnd);
     670             :             }
     671             :         }
     672           0 :         aP2 = GetAnglePnt(aR,nEnd);
     673           0 :     } else aP2=aCenter;
     674           0 : }
     675             : 
     676           0 : void SdrCircObj::ImpSetCreateParams(SdrDragStat& rStat) const
     677             : {
     678           0 :     ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
     679           0 :     if (pU==NULL) {
     680           0 :         pU=new ImpCircUser;
     681           0 :         rStat.SetUser(pU);
     682             :     }
     683           0 :     pU->SetCreateParams(rStat);
     684           0 : }
     685             : 
     686           0 : bool SdrCircObj::BegCreate(SdrDragStat& rStat)
     687             : {
     688           0 :     rStat.SetOrtho4Possible();
     689           0 :     Rectangle aRect1(rStat.GetStart(), rStat.GetNow());
     690           0 :     aRect1.Justify();
     691           0 :     rStat.SetActionRect(aRect1);
     692           0 :     maRect = aRect1;
     693           0 :     ImpSetCreateParams(rStat);
     694           0 :     return true;
     695             : }
     696             : 
     697           0 : bool SdrCircObj::MovCreate(SdrDragStat& rStat)
     698             : {
     699           0 :     ImpSetCreateParams(rStat);
     700           0 :     ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
     701           0 :     rStat.SetActionRect(pU->aR);
     702           0 :     maRect = pU->aR; // for ObjName
     703           0 :     ImpJustifyRect(maRect);
     704           0 :     nStartAngle=pU->nStart;
     705           0 :     nEndAngle=pU->nEnd;
     706           0 :     SetBoundRectDirty();
     707           0 :     bSnapRectDirty=true;
     708           0 :     SetXPolyDirty();
     709             : 
     710             :     // #i103058# push current angle settings to ItemSet to
     711             :     // allow FullDrag visualisation
     712           0 :     if(rStat.GetPointAnz() >= 4)
     713             :     {
     714           0 :         ImpSetCircInfoToAttr();
     715             :     }
     716             : 
     717           0 :     return true;
     718             : }
     719             : 
     720           0 : bool SdrCircObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
     721             : {
     722           0 :     ImpSetCreateParams(rStat);
     723           0 :     ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
     724           0 :     bool bRet = false;
     725           0 :     if (eCmd==SDRCREATE_FORCEEND && rStat.GetPointAnz()<4) meCircleKind=OBJ_CIRC;
     726           0 :     if (meCircleKind==OBJ_CIRC) {
     727           0 :         bRet=rStat.GetPointAnz()>=2;
     728           0 :         if (bRet) {
     729           0 :             maRect = pU->aR;
     730           0 :             ImpJustifyRect(maRect);
     731             :         }
     732             :     } else {
     733           0 :         rStat.SetNoSnap(rStat.GetPointAnz()>=2);
     734           0 :         rStat.SetOrtho4Possible(rStat.GetPointAnz()<2);
     735           0 :         bRet=rStat.GetPointAnz()>=4;
     736           0 :         if (bRet) {
     737           0 :             maRect = pU->aR;
     738           0 :             ImpJustifyRect(maRect);
     739           0 :             nStartAngle=pU->nStart;
     740           0 :             nEndAngle=pU->nEnd;
     741             :         }
     742             :     }
     743           0 :     bClosedObj=meCircleKind!=OBJ_CARC;
     744           0 :     SetRectsDirty();
     745           0 :     SetXPolyDirty();
     746           0 :     ImpSetCircInfoToAttr();
     747           0 :     if (bRet) {
     748           0 :         delete pU;
     749           0 :         rStat.SetUser(NULL);
     750             :     }
     751           0 :     return bRet;
     752             : }
     753             : 
     754           0 : void SdrCircObj::BrkCreate(SdrDragStat& rStat)
     755             : {
     756           0 :     ImpCircUser* pU=static_cast<ImpCircUser*>(rStat.GetUser());
     757           0 :     delete pU;
     758           0 :     rStat.SetUser(NULL);
     759           0 : }
     760             : 
     761           0 : bool SdrCircObj::BckCreate(SdrDragStat& rStat)
     762             : {
     763           0 :     rStat.SetNoSnap(rStat.GetPointAnz()>=3);
     764           0 :     rStat.SetOrtho4Possible(rStat.GetPointAnz()<3);
     765           0 :     return meCircleKind!=OBJ_CIRC;
     766             : }
     767             : 
     768           0 : basegfx::B2DPolyPolygon SdrCircObj::TakeCreatePoly(const SdrDragStat& rDrag) const
     769             : {
     770           0 :     const ImpCircUser* pU = static_cast<const ImpCircUser*>(rDrag.GetUser());
     771             : 
     772           0 :     if(rDrag.GetPointAnz() < 4L)
     773             :     {
     774             :         // force to OBJ_CIRC to get full visualisation
     775           0 :         basegfx::B2DPolyPolygon aRetval(ImpCalcXPolyCirc(OBJ_CIRC, pU->aR, pU->nStart, pU->nEnd));
     776             : 
     777           0 :         if(3L == rDrag.GetPointAnz())
     778             :         {
     779             :             // add edge to first point on ellipse
     780           0 :             basegfx::B2DPolygon aNew;
     781             : 
     782           0 :             aNew.append(basegfx::B2DPoint(pU->aCenter.X(), pU->aCenter.Y()));
     783           0 :             aNew.append(basegfx::B2DPoint(pU->aP1.X(), pU->aP1.Y()));
     784           0 :             aRetval.append(aNew);
     785             :         }
     786             : 
     787           0 :         return aRetval;
     788             :     }
     789             :     else
     790             :     {
     791           0 :         return basegfx::B2DPolyPolygon(ImpCalcXPolyCirc(meCircleKind, pU->aR, pU->nStart, pU->nEnd));
     792             :     }
     793             : }
     794             : 
     795           0 : Pointer SdrCircObj::GetCreatePointer() const
     796             : {
     797           0 :     switch (meCircleKind) {
     798           0 :         case OBJ_CIRC: return Pointer(PointerStyle::DrawEllipse);
     799           0 :         case OBJ_SECT: return Pointer(PointerStyle::DrawPie);
     800           0 :         case OBJ_CARC: return Pointer(PointerStyle::DrawArc);
     801           0 :         case OBJ_CCUT: return Pointer(PointerStyle::DrawCircleCut);
     802           0 :         default: break;
     803             :     } // switch
     804           0 :     return Pointer(PointerStyle::Cross);
     805             : }
     806             : 
     807         142 : void SdrCircObj::NbcMove(const Size& aSiz)
     808             : {
     809         142 :     MoveRect(maRect,aSiz);
     810         142 :     MoveRect(aOutRect,aSiz);
     811         142 :     MoveRect(maSnapRect,aSiz);
     812         142 :     SetXPolyDirty();
     813         142 :     SetRectsDirty(true);
     814         142 : }
     815             : 
     816          10 : void SdrCircObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
     817             : {
     818          10 :     long nAngle0=aGeo.nRotationAngle;
     819          10 :     bool bNoShearRota=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
     820          10 :     SdrTextObj::NbcResize(rRef,xFact,yFact);
     821          10 :     bNoShearRota|=(aGeo.nRotationAngle==0 && aGeo.nShearAngle==0);
     822          10 :     if (meCircleKind!=OBJ_CIRC) {
     823          10 :         bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
     824          10 :         bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
     825          10 :         if (bXMirr || bYMirr) {
     826             :             // At bXMirr!=bYMirr we should actually swap both line ends.
     827             :             // That, however, is pretty bad (because of forced "hard" formatting).
     828             :             // Alternatively, we could implement a bMirrored flag (maybe even
     829             :             // a more general one, e. g. for mirrored text, ...).
     830           0 :             long nS0=nStartAngle;
     831           0 :             long nE0=nEndAngle;
     832           0 :             if (bNoShearRota) {
     833             :                 // the RectObj already mirrors at VMirror because of a 180deg rotation
     834           0 :                 if (! (bXMirr && bYMirr)) {
     835           0 :                     long nTmp=nS0;
     836           0 :                     nS0=18000-nE0;
     837           0 :                     nE0=18000-nTmp;
     838             :                 }
     839             :             } else { // mirror contorted ellipses
     840           0 :                 if (bXMirr!=bYMirr) {
     841           0 :                     nS0+=nAngle0;
     842           0 :                     nE0+=nAngle0;
     843           0 :                     if (bXMirr) {
     844           0 :                         long nTmp=nS0;
     845           0 :                         nS0=18000-nE0;
     846           0 :                         nE0=18000-nTmp;
     847             :                     }
     848           0 :                     if (bYMirr) {
     849           0 :                         long nTmp=nS0;
     850           0 :                         nS0=-nE0;
     851           0 :                         nE0=-nTmp;
     852             :                     }
     853           0 :                     nS0-=aGeo.nRotationAngle;
     854           0 :                     nE0-=aGeo.nRotationAngle;
     855             :                 }
     856             :             }
     857           0 :             long nAngleDif=nE0-nS0;
     858           0 :             nStartAngle=NormAngle360(nS0);
     859           0 :             nEndAngle  =NormAngle360(nE0);
     860           0 :             if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
     861             :         }
     862             :     }
     863          10 :     SetXPolyDirty();
     864          10 :     ImpSetCircInfoToAttr();
     865          10 : }
     866             : 
     867           0 : void SdrCircObj::NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear)
     868             : {
     869           0 :     SdrTextObj::NbcShear(rRef,nAngle,tn,bVShear);
     870           0 :     SetXPolyDirty();
     871           0 :     ImpSetCircInfoToAttr();
     872           0 : }
     873             : 
     874           0 : void SdrCircObj::NbcMirror(const Point& rRef1, const Point& rRef2)
     875             : {
     876           0 :     bool bFreeMirr=meCircleKind!=OBJ_CIRC;
     877           0 :     Point aTmpPt1;
     878           0 :     Point aTmpPt2;
     879           0 :     if (bFreeMirr) { // some preparations for using an arbitrary axis of reflection
     880           0 :         Point aCenter(maRect.Center());
     881           0 :         long nWdt=maRect.GetWidth()-1;
     882           0 :         long nHgt=maRect.GetHeight()-1;
     883           0 :         long nMaxRad=((nWdt>nHgt ? nWdt : nHgt)+1) /2;
     884             :         double a;
     885             :         // starting point
     886           0 :         a=nStartAngle*nPi180;
     887           0 :         aTmpPt1=Point(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
     888           0 :         if (nWdt==0) aTmpPt1.X()=0;
     889           0 :         if (nHgt==0) aTmpPt1.Y()=0;
     890           0 :         aTmpPt1+=aCenter;
     891             :         // finishing point
     892           0 :         a=nEndAngle*nPi180;
     893           0 :         aTmpPt2=Point(Round(cos(a)*nMaxRad),-Round(sin(a)*nMaxRad));
     894           0 :         if (nWdt==0) aTmpPt2.X()=0;
     895           0 :         if (nHgt==0) aTmpPt2.Y()=0;
     896           0 :         aTmpPt2+=aCenter;
     897           0 :         if (aGeo.nRotationAngle!=0) {
     898           0 :             RotatePoint(aTmpPt1,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
     899           0 :             RotatePoint(aTmpPt2,maRect.TopLeft(),aGeo.nSin,aGeo.nCos);
     900             :         }
     901           0 :         if (aGeo.nShearAngle!=0) {
     902           0 :             ShearPoint(aTmpPt1,maRect.TopLeft(),aGeo.nTan);
     903           0 :             ShearPoint(aTmpPt2,maRect.TopLeft(),aGeo.nTan);
     904             :         }
     905             :     }
     906           0 :     SdrTextObj::NbcMirror(rRef1,rRef2);
     907           0 :     if (meCircleKind!=OBJ_CIRC) { // adapt starting and finishing angle
     908           0 :         MirrorPoint(aTmpPt1,rRef1,rRef2);
     909           0 :         MirrorPoint(aTmpPt2,rRef1,rRef2);
     910             :         // unrotate:
     911           0 :         if (aGeo.nRotationAngle!=0) {
     912           0 :             RotatePoint(aTmpPt1,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
     913           0 :             RotatePoint(aTmpPt2,maRect.TopLeft(),-aGeo.nSin,aGeo.nCos); // -sin for reversion
     914             :         }
     915             :         // unshear:
     916           0 :         if (aGeo.nShearAngle!=0) {
     917           0 :             ShearPoint(aTmpPt1,maRect.TopLeft(),-aGeo.nTan); // -tan for reversion
     918           0 :             ShearPoint(aTmpPt2,maRect.TopLeft(),-aGeo.nTan); // -tan for reversion
     919             :         }
     920           0 :         Point aCenter(maRect.Center());
     921           0 :         aTmpPt1-=aCenter;
     922           0 :         aTmpPt2-=aCenter;
     923             :         // because it's mirrored, the angles are swapped, too
     924           0 :         nStartAngle=GetAngle(aTmpPt2);
     925           0 :         nEndAngle  =GetAngle(aTmpPt1);
     926           0 :         long nAngleDif=nEndAngle-nStartAngle;
     927           0 :         nStartAngle=NormAngle360(nStartAngle);
     928           0 :         nEndAngle  =NormAngle360(nEndAngle);
     929           0 :         if (nAngleDif==36000) nEndAngle+=nAngleDif; // full circle
     930             :     }
     931           0 :     SetXPolyDirty();
     932           0 :     ImpSetCircInfoToAttr();
     933           0 : }
     934             : 
     935           0 : SdrObjGeoData* SdrCircObj::NewGeoData() const
     936             : {
     937           0 :     return new SdrCircObjGeoData;
     938             : }
     939             : 
     940           0 : void SdrCircObj::SaveGeoData(SdrObjGeoData& rGeo) const
     941             : {
     942           0 :     SdrRectObj::SaveGeoData(rGeo);
     943           0 :     SdrCircObjGeoData& rCGeo=static_cast<SdrCircObjGeoData&>(rGeo);
     944           0 :     rCGeo.nStartAngle=nStartAngle;
     945           0 :     rCGeo.nEndAngle  =nEndAngle;
     946           0 : }
     947             : 
     948           0 : void SdrCircObj::RestGeoData(const SdrObjGeoData& rGeo)
     949             : {
     950           0 :     SdrRectObj::RestGeoData(rGeo);
     951           0 :     const SdrCircObjGeoData& rCGeo=static_cast<const SdrCircObjGeoData&>(rGeo);
     952           0 :     nStartAngle=rCGeo.nStartAngle;
     953           0 :     nEndAngle  =rCGeo.nEndAngle;
     954           0 :     SetXPolyDirty();
     955           0 :     ImpSetCircInfoToAttr();
     956           0 : }
     957             : 
     958           0 : void Union(Rectangle& rR, const Point& rP)
     959             : {
     960           0 :     if (rP.X()<rR.Left  ()) rR.Left  ()=rP.X();
     961           0 :     if (rP.X()>rR.Right ()) rR.Right ()=rP.X();
     962           0 :     if (rP.Y()<rR.Top   ()) rR.Top   ()=rP.Y();
     963           0 :     if (rP.Y()>rR.Bottom()) rR.Bottom()=rP.Y();
     964           0 : }
     965             : 
     966          83 : void SdrCircObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
     967             : {
     968          83 :     rRect = maRect;
     969          83 :     if (meCircleKind!=OBJ_CIRC) {
     970           0 :         const Point aPntStart(GetAnglePnt(maRect,nStartAngle));
     971           0 :         const Point aPntEnd(GetAnglePnt(maRect,nEndAngle));
     972           0 :         long a=nStartAngle;
     973           0 :         long e=nEndAngle;
     974           0 :         rRect.Left  ()=maRect.Right();
     975           0 :         rRect.Right ()=maRect.Left();
     976           0 :         rRect.Top   ()=maRect.Bottom();
     977           0 :         rRect.Bottom()=maRect.Top();
     978           0 :         Union(rRect,aPntStart);
     979           0 :         Union(rRect,aPntEnd);
     980           0 :         if ((a<=18000 && e>=18000) || (a>e && (a<=18000 || e>=18000))) {
     981           0 :             Union(rRect,maRect.LeftCenter());
     982             :         }
     983           0 :         if ((a<=27000 && e>=27000) || (a>e && (a<=27000 || e>=27000))) {
     984           0 :             Union(rRect,maRect.BottomCenter());
     985             :         }
     986           0 :         if (a>e) {
     987           0 :             Union(rRect,maRect.RightCenter());
     988             :         }
     989           0 :         if ((a<=9000 && e>=9000) || (a>e && (a<=9000 || e>=9000))) {
     990           0 :             Union(rRect,maRect.TopCenter());
     991             :         }
     992           0 :         if (meCircleKind==OBJ_SECT) {
     993           0 :             Union(rRect,maRect.Center());
     994             :         }
     995           0 :         if (aGeo.nRotationAngle!=0) {
     996           0 :             Point aDst(rRect.TopLeft());
     997           0 :             aDst-=maRect.TopLeft();
     998           0 :             Point aDst0(aDst);
     999           0 :             RotatePoint(aDst,Point(),aGeo.nSin,aGeo.nCos);
    1000           0 :             aDst-=aDst0;
    1001           0 :             rRect.Move(aDst.X(),aDst.Y());
    1002             :         }
    1003             :     }
    1004          83 :     if (aGeo.nShearAngle!=0) {
    1005           0 :         long nDst=Round((rRect.Bottom()-rRect.Top())*aGeo.nTan);
    1006           0 :         if (aGeo.nShearAngle>0) {
    1007           0 :             Point aRef(rRect.TopLeft());
    1008           0 :             rRect.Left()-=nDst;
    1009           0 :             Point aTmpPt(rRect.TopLeft());
    1010           0 :             RotatePoint(aTmpPt,aRef,aGeo.nSin,aGeo.nCos);
    1011           0 :             aTmpPt-=rRect.TopLeft();
    1012           0 :             rRect.Move(aTmpPt.X(),aTmpPt.Y());
    1013             :         } else {
    1014           0 :             rRect.Right()-=nDst;
    1015             :         }
    1016             :     }
    1017          83 : }
    1018             : 
    1019         149 : void SdrCircObj::RecalcSnapRect()
    1020             : {
    1021         149 :     if (PaintNeedsXPolyCirc()) {
    1022          66 :         maSnapRect=GetXPoly().GetBoundRect();
    1023             :     } else {
    1024          83 :         TakeUnrotatedSnapRect(maSnapRect);
    1025             :     }
    1026         149 : }
    1027             : 
    1028          58 : void SdrCircObj::NbcSetSnapRect(const Rectangle& rRect)
    1029             : {
    1030          58 :     if (aGeo.nRotationAngle!=0 || aGeo.nShearAngle!=0 || meCircleKind!=OBJ_CIRC) {
    1031          10 :         Rectangle aSR0(GetSnapRect());
    1032          10 :         long nWdt0=aSR0.Right()-aSR0.Left();
    1033          10 :         long nHgt0=aSR0.Bottom()-aSR0.Top();
    1034          10 :         long nWdt1=rRect.Right()-rRect.Left();
    1035          10 :         long nHgt1=rRect.Bottom()-rRect.Top();
    1036          10 :         NbcResize(maSnapRect.TopLeft(),Fraction(nWdt1,nWdt0),Fraction(nHgt1,nHgt0));
    1037          10 :         NbcMove(Size(rRect.Left()-aSR0.Left(),rRect.Top()-aSR0.Top()));
    1038             :     } else {
    1039          48 :         maRect=rRect;
    1040          48 :         ImpJustifyRect(maRect);
    1041             :     }
    1042          58 :     SetRectsDirty();
    1043          58 :     SetXPolyDirty();
    1044          58 :     ImpSetCircInfoToAttr();
    1045          58 : }
    1046             : 
    1047           0 : sal_uInt32 SdrCircObj::GetSnapPointCount() const
    1048             : {
    1049           0 :     if (meCircleKind==OBJ_CIRC) {
    1050           0 :         return 1L;
    1051             :     } else {
    1052           0 :         return 3L;
    1053             :     }
    1054             : }
    1055             : 
    1056           0 : Point SdrCircObj::GetSnapPoint(sal_uInt32 i) const
    1057             : {
    1058           0 :     switch (i) {
    1059           0 :         case 1 : return GetAnglePnt(maRect,nStartAngle);
    1060           0 :         case 2 : return GetAnglePnt(maRect,nEndAngle);
    1061           0 :         default: return maRect.Center();
    1062             :     }
    1063             : }
    1064             : 
    1065         182 : void SdrCircObj::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
    1066             : {
    1067         182 :     SetXPolyDirty();
    1068         182 :     SdrRectObj::Notify(rBC,rHint);
    1069         182 :     ImpSetAttrToCircInfo();
    1070         182 : }
    1071             : 
    1072             : 
    1073             : 
    1074         844 : void SdrCircObj::ImpSetAttrToCircInfo()
    1075             : {
    1076         844 :     const SfxItemSet& rSet = GetObjectItemSet();
    1077         844 :     SdrCircKind eNewKindA = static_cast<const SdrCircKindItem&>(rSet.Get(SDRATTR_CIRCKIND)).GetValue();
    1078         844 :     SdrObjKind eNewKind = meCircleKind;
    1079             : 
    1080         844 :     if(eNewKindA == SDRCIRC_FULL)
    1081         569 :         eNewKind = OBJ_CIRC;
    1082         275 :     else if(eNewKindA == SDRCIRC_SECT)
    1083          94 :         eNewKind = OBJ_SECT;
    1084         181 :     else if(eNewKindA == SDRCIRC_ARC)
    1085          72 :         eNewKind = OBJ_CARC;
    1086         109 :     else if(eNewKindA == SDRCIRC_CUT)
    1087         109 :         eNewKind = OBJ_CCUT;
    1088             : 
    1089         844 :     sal_Int32 nNewStart = static_cast<const SdrAngleItem&>(rSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue();
    1090         844 :     sal_Int32 nNewEnd = static_cast<const SdrAngleItem&>(rSet.Get(SDRATTR_CIRCENDANGLE)).GetValue();
    1091             : 
    1092         844 :     bool bKindChg = meCircleKind != eNewKind;
    1093         844 :     bool bAngleChg = nNewStart != nStartAngle || nNewEnd != nEndAngle;
    1094             : 
    1095         844 :     if(bKindChg || bAngleChg)
    1096             :     {
    1097         123 :         meCircleKind = eNewKind;
    1098         123 :         nStartAngle = nNewStart;
    1099         123 :         nEndAngle = nNewEnd;
    1100             : 
    1101         123 :         if(bKindChg || (meCircleKind != OBJ_CIRC && bAngleChg))
    1102             :         {
    1103         123 :             SetXPolyDirty();
    1104         123 :             SetRectsDirty();
    1105             :         }
    1106             :     }
    1107         844 : }
    1108             : 
    1109          68 : void SdrCircObj::ImpSetCircInfoToAttr()
    1110             : {
    1111          68 :     SdrCircKind eNewKindA = SDRCIRC_FULL;
    1112          68 :     const SfxItemSet& rSet = GetObjectItemSet();
    1113             : 
    1114          68 :     if(meCircleKind == OBJ_SECT)
    1115           0 :         eNewKindA = SDRCIRC_SECT;
    1116          68 :     else if(meCircleKind == OBJ_CARC)
    1117           0 :         eNewKindA = SDRCIRC_ARC;
    1118          68 :     else if(meCircleKind == OBJ_CCUT)
    1119          20 :         eNewKindA = SDRCIRC_CUT;
    1120             : 
    1121          68 :     SdrCircKind eOldKindA = static_cast<const SdrCircKindItem&>(rSet.Get(SDRATTR_CIRCKIND)).GetValue();
    1122          68 :     sal_Int32 nOldStartAngle = static_cast<const SdrAngleItem&>(rSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue();
    1123          68 :     sal_Int32 nOldEndAngle = static_cast<const SdrAngleItem&>(rSet.Get(SDRATTR_CIRCENDANGLE)).GetValue();
    1124             : 
    1125          68 :     if(eNewKindA != eOldKindA || nStartAngle != nOldStartAngle || nEndAngle != nOldEndAngle)
    1126             :     {
    1127             :         // since SetItem() implicitly calls ImpSetAttrToCircInfo()
    1128             :         // setting the item directly is necessary here.
    1129           0 :         if(eNewKindA != eOldKindA)
    1130             :         {
    1131           0 :             GetProperties().SetObjectItemDirect(SdrCircKindItem(eNewKindA));
    1132             :         }
    1133             : 
    1134           0 :         if(nStartAngle != nOldStartAngle)
    1135             :         {
    1136           0 :             GetProperties().SetObjectItemDirect(makeSdrCircStartAngleItem(nStartAngle));
    1137             :         }
    1138             : 
    1139           0 :         if(nEndAngle != nOldEndAngle)
    1140             :         {
    1141           0 :             GetProperties().SetObjectItemDirect(makeSdrCircEndAngleItem(nEndAngle));
    1142             :         }
    1143             : 
    1144           0 :         SetXPolyDirty();
    1145           0 :         ImpSetAttrToCircInfo();
    1146             :     }
    1147          68 : }
    1148             : 
    1149           3 : SdrObject* SdrCircObj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
    1150             : {
    1151           3 :     const bool bFill(meCircleKind != OBJ_CARC);
    1152           3 :     const basegfx::B2DPolygon aCircPolygon(ImpCalcXPolyCirc(meCircleKind, maRect, nStartAngle, nEndAngle));
    1153           3 :     SdrObject* pRet = ImpConvertMakeObj(basegfx::B2DPolyPolygon(aCircPolygon), bFill, bBezier);
    1154             : 
    1155           3 :     if(bAddText)
    1156             :     {
    1157           3 :         pRet = ImpConvertAddText(pRet, bBezier);
    1158             :     }
    1159             : 
    1160           3 :     return pRet;
    1161         435 : }
    1162             : 
    1163             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11