LCOV - code coverage report
Current view: top level - svx/source/svdraw - svdocirc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 179 655 27.3 %
Date: 2012-08-25 Functions: 25 55 45.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 112 787 14.2 %

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

Generated by: LCOV version 1.10