LCOV - code coverage report
Current view: top level - svx/inc/svx - svdtrans.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 31 51 60.8 %
Date: 2012-08-25 Functions: 17 23 73.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 31 64 48.4 %

           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                 :            : #ifndef _SVDTRANS_HXX
      30                 :            : #define _SVDTRANS_HXX
      31                 :            : 
      32                 :            : #include <tools/gen.hxx>
      33                 :            : #include <tools/poly.hxx>
      34                 :            : #include <tools/fract.hxx>
      35                 :            : 
      36                 :            : #include <vcl/mapmod.hxx>
      37                 :            : #include <tools/string.hxx>
      38                 :            : #include "svx/svxdllapi.h"
      39                 :            : 
      40                 :            : #include <vcl/field.hxx>
      41                 :            : 
      42                 :            : ////////////////////////////////////////////////////////////////////////////////////////////////////
      43                 :            : 
      44                 :            : // Winkelangaben der DrawingEngine sind 1/100 Degree
      45                 :            : // #i19054# nowhere used, removed // const int nWinkDiv=100;
      46                 :            : // Um Winkel der DrawingEngine mit den Trigonometrischen Funktionen
      47                 :            : // verarbeiten zu koennen, muessen sie zunaest ins Bogenmass umgerechnet
      48                 :            : // werden. Dies gestaltet sich recht einfach mit der folgenden Konstanten
      49                 :            : // nPi180. Sei nWink ein Winkel in 1/100 Deg so schreibt man z.B.:
      50                 :            : //   double nSin=sin(nWink*nPi180);
      51                 :            : // Rueckwandlung entsprechend durch Teilen.
      52                 :            : const double nPi=3.14159265358979323846;
      53                 :            : const double nPi180=0.000174532925199432957692222; // Bei zuweing Stellen ist tan(4500*nPi180)!=1.0
      54                 :            : 
      55                 :            : // Der maximale Shearwinkel
      56                 :            : #define SDRMAXSHEAR 8900
      57                 :            : 
      58                 :            : class XPolygon;
      59                 :            : class XPolyPolygon;
      60                 :            : 
      61         [ +  + ]:     844151 : inline long Round(double a) { return a>0.0 ? (long)(a+0.5) : -(long)((-a)+0.5); }
      62                 :            : 
      63                 :     283022 : inline void MoveRect(Rectangle& rRect, const Size& S)    { rRect.Move(S.Width(),S.Height()); }
      64                 :      13793 : inline void MovePoint(Point& rPnt, const Size& S)        { rPnt.X()+=S.Width(); rPnt.Y()+=S.Height(); }
      65                 :          3 : inline void MovePoly(Polygon& rPoly, const Size& S)      { rPoly.Move(S.Width(),S.Height()); }
      66                 :            : inline void MovePoly(PolyPolygon& rPoly, const Size& S)  { rPoly.Move(S.Width(),S.Height()); }
      67                 :            : void MoveXPoly(XPolygon& rPoly, const Size& S);
      68                 :            : 
      69                 :            : SVX_DLLPUBLIC void ResizeRect(Rectangle& rRect, const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bNoJustify = false);
      70                 :            : inline void ResizePoint(Point& rPnt, const Point& rRef, Fraction xFact, Fraction yFact);
      71                 :            : void ResizePoly(Polygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact);
      72                 :            : void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact);
      73                 :            : 
      74                 :            : inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs);
      75                 :            : SVX_DLLPUBLIC void RotatePoly(Polygon& rPoly, const Point& rRef, double sn, double cs);
      76                 :            : void RotateXPoly(XPolygon& rPoly, const Point& rRef, double sn, double cs);
      77                 :            : void RotateXPoly(XPolyPolygon& rPoly, const Point& rRef, double sn, double cs);
      78                 :            : 
      79                 :            : void MirrorPoint(Point& rPnt, const Point& rRef1, const Point& rRef2);
      80                 :            : void MirrorPoly(Polygon& rPoly, const Point& rRef1, const Point& rRef2);
      81                 :            : void MirrorXPoly(XPolygon& rPoly, const Point& rRef1, const Point& rRef2);
      82                 :            : 
      83                 :            : inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear = false);
      84                 :            : SVX_DLLPUBLIC void ShearPoly(Polygon& rPoly, const Point& rRef, double tn, bool bVShear = false);
      85                 :            : void ShearXPoly(XPolygon& rPoly, const Point& rRef, double tn, bool bVShear = false);
      86                 :            : 
      87                 :            : // rPnt.X bzw rPnt.Y wird auf rCenter.X bzw. rCenter.Y gesetzt!
      88                 :            : // anschliessend muss rPnt nur noch um rCenter gedreht werden.
      89                 :            : // Der Rueckgabewinkel ist ausnahmsweise in Rad.
      90                 :            : inline double GetCrookAngle(Point& rPnt, const Point& rCenter, const Point& rRad, bool bVertical);
      91                 :            : // Die folgenden Methoden behandeln einen Punkt eines XPolygons, wobei die
      92                 :            : // benachbarten Kontrollpunkte des eigentlichen Punktes ggf. in pC1/pC2
      93                 :            : // uebergeben werden. Ueber rSin/rCos wird gleichzeitig sin(nWink) und cos(nWink)
      94                 :            : // zurueckgegeben.
      95                 :            : // Der Rueckgabewinkel ist hier ebenfalls in Rad.
      96                 :            : double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
      97                 :            :                          const Point& rRad, double& rSin, double& rCos, bool bVert);
      98                 :            : double CrookSlantXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
      99                 :            :                         const Point& rRad, double& rSin, double& rCos, bool bVert);
     100                 :            : double CrookStretchXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
     101                 :            :                           const Point& rRad, double& rSin, double& rCos, bool bVert,
     102                 :            :                           const Rectangle rRefRect);
     103                 :            : 
     104                 :            : void CrookRotatePoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
     105                 :            : void CrookSlantPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
     106                 :            : void CrookStretchPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert, const Rectangle rRefRect);
     107                 :            : 
     108                 :            : void CrookRotatePoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
     109                 :            : void CrookSlantPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
     110                 :            : void CrookStretchPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert, const Rectangle rRefRect);
     111                 :            : 
     112                 :            : /**************************************************************************************************/
     113                 :            : /*  Inline                                                                                        */
     114                 :            : /**************************************************************************************************/
     115                 :            : 
     116                 :     158071 : inline void ResizePoint(Point& rPnt, const Point& rRef, Fraction xFact, Fraction yFact)
     117                 :            : {
     118 [ -  + ][ #  # ]:     158071 :     if (xFact.GetDenominator()==0) xFact=Fraction(xFact.GetNumerator(),1); // DivZero abfangen
     119 [ -  + ][ #  # ]:     158071 :     if (yFact.GetDenominator()==0) yFact=Fraction(yFact.GetNumerator(),1); // DivZero abfangen
     120                 :     158071 :     rPnt.X()=rRef.X()+ Round(((double)(rPnt.X()-rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
     121                 :     158071 :     rPnt.Y()=rRef.Y()+ Round(((double)(rPnt.Y()-rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
     122                 :     158071 : }
     123                 :            : 
     124                 :      97971 : inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs)
     125                 :            : {
     126                 :      97971 :     long dx=rPnt.X()-rRef.X();
     127                 :      97971 :     long dy=rPnt.Y()-rRef.Y();
     128                 :      97971 :     rPnt.X()=Round(rRef.X()+dx*cs+dy*sn);
     129                 :      97971 :     rPnt.Y()=Round(rRef.Y()+dy*cs-dx*sn);
     130                 :      97971 : }
     131                 :            : 
     132                 :          0 : inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear)
     133                 :            : {
     134         [ #  # ]:          0 :     if (!bVShear) { // Horizontal
     135         [ #  # ]:          0 :         if (rPnt.Y()!=rRef.Y()) { // sonst nicht noetig
     136                 :          0 :             rPnt.X()-=Round((rPnt.Y()-rRef.Y())*tn);
     137                 :            :         }
     138                 :            :     } else { // ansonsten vertikal
     139         [ #  # ]:          0 :         if (rPnt.X()!=rRef.X()) { // sonst nicht noetig
     140                 :          0 :             rPnt.Y()-=Round((rPnt.X()-rRef.X())*tn);
     141                 :            :         }
     142                 :            :     }
     143                 :          0 : }
     144                 :            : 
     145                 :          0 : inline double GetCrookAngle(Point& rPnt, const Point& rCenter, const Point& rRad, bool bVertical)
     146                 :            : {
     147                 :            :     double nWink;
     148         [ #  # ]:          0 :     if (bVertical) {
     149                 :          0 :         long dy=rPnt.Y()-rCenter.Y();
     150                 :          0 :         nWink=(double)dy/(double)rRad.Y();
     151                 :          0 :         rPnt.Y()=rCenter.Y();
     152                 :            :     } else {
     153                 :          0 :         long dx=rCenter.X()-rPnt.X();
     154                 :          0 :         nWink=(double)dx/(double)rRad.X();
     155                 :          0 :         rPnt.X()=rCenter.X();
     156                 :            :     }
     157                 :          0 :     return nWink;
     158                 :            : }
     159                 :            : 
     160                 :            : /**************************************************************************************************/
     161                 :            : /**************************************************************************************************/
     162                 :            : 
     163                 :            : // Y-Achse zeigt nach unten! Die Funktion negiert bei der
     164                 :            : // Winkelberechnung die Y-Achse, sodass GetAngle(Point(0,-1))=90.00deg.
     165                 :            : // GetAngle(Point(0,0)) liefert 0.
     166                 :            : // Der Rueckgabewert liegt im Bereich -180.00..179.99 Degree und
     167                 :            : // ist in 1/100 Degree angegeben.
     168                 :            : SVX_DLLPUBLIC long GetAngle(const Point& rPnt);
     169                 :            : long NormAngle180(long a); // Winkel normalisieren auf -180.00..179.99
     170                 :            : SVX_DLLPUBLIC long NormAngle360(long a); // Winkel normalisieren auf    0.00..359.99
     171                 :            : sal_uInt16 GetAngleSector(long nWink); // Sektor im kartesischen Koordinatensystem bestimmen
     172                 :            : // Berechnet die Laenge von (0,0) via a^2 + b^2 = c^2
     173                 :            : // Zur Vermeidung von Ueberlaeufen werden ggf. einige Stellen ignoriert.
     174                 :            : long GetLen(const Point& rPnt);
     175                 :            : 
     176                 :            : /*
     177                 :            :   Transformation eines Rechtecks in ein Polygon unter            ------------
     178                 :            :   Anwendung der Winkelparameter aus GeoStat.                    /1        2/
     179                 :            :   Referenzpunkt ist stets der Punkt 0, also die linke          /          /
     180                 :            :   obere Ecke des Ausgangsrects.                               /          /
     181                 :            :   Bei der Berechnung des Polygons ist die Reihenfolge        /          /
     182                 :            :   (erst Shear, dann Rotation vorgegeben).                   /          / \
     183                 :            :                                                            /          /   |
     184                 :            :   A) Ausgangsrechteck aRect  B) Nach Anwendung von Shear  /0        3/  Rot|
     185                 :            :   +------------------+       --------------------        ------------  ------
     186                 :            :   |0                1|        \0                1\       C) Nach Anwendung
     187                 :            :   |                  |         \                  \      von Rotate
     188                 :            :   |                  |       |  \                  \
     189                 :            :   |3                2|       |   \3                2\
     190                 :            :   +------------------+       |    --------------------
     191                 :            :                              |Shr |
     192                 :            :   Bei Rueckkonvertierung des        Polygons in ein Rect ist die Reihenfolge
     193                 :            :   zwangslaeufig umgekehrt:
     194                 :            :   - Berechnung des Drehwinkels: Winkel der Strecke 0-1 aus Abb. C) zum Horizont
     195                 :            :   - Rueckdrehung des geshearten Rects (man erhaelt Abb B))
     196                 :            :   - Bestimmung der Breite des Rects=Laenge der Strecke 0-1 aus Abb. B)
     197                 :            :   - Bestimmung der Hoehe des Rects=vertikaler Abstand zwischen den Punkten
     198                 :            :     0 und 3 aus Abb. B)
     199                 :            :   - Bestimmung des Shear-Winkels aus der Strecke 0-3 zur Senkrechten.
     200                 :            :   Es ist darauf zu achten, dass das Polygon bei einer zwischenzeitlichen
     201                 :            :   Transformation evtl. gespiegelt wurde (Mirror oder Resize mit neg. Faktor).
     202                 :            :   In diesem Fall muss zunaecht eine Normalisierung durch Vertauschung der
     203                 :            :   Punkte (z.B. 0 mit 3 und 1 mit 2) durchgefuehrt werden, damit der
     204                 :            :   Richtungssinn im Polygon wieder stimmig ist.
     205                 :            :   Hinweis: Positiver Shear-Winkel bedeutet Shear mit auf dem Bildschirm
     206                 :            :   sichtbarer positiver Kursivierung. Mathematisch waere dass eine negative
     207                 :            :   Kursivierung, da die Y-Achse auf dem Bildschirm von oben nach unten verlaeuft.
     208                 :            :   Drehwinkel: Positiv bedeutet auf dem Bildschirm sichtbare Linksdrehung.
     209                 :            : */
     210                 :            : 
     211                 :            : class GeoStat { // Geometrischer Status fuer ein Rect
     212                 :            : public:
     213                 :            :     long     nDrehWink;
     214                 :            :     long     nShearWink;
     215                 :            :     double   nTan;      // tan(nShearWink)
     216                 :            :     double   nSin;      // sin(nDrehWink)
     217                 :            :     double   nCos;      // cos(nDrehWink)
     218                 :            :     bool     bMirrored; // Horizontal gespiegelt? (ni)
     219                 :            : public:
     220                 :      58735 :     GeoStat(): nDrehWink(0),nShearWink(0),nTan(0.0),nSin(0.0),nCos(1.0),bMirrored(false) {}
     221                 :            :     void RecalcSinCos();
     222                 :            :     void RecalcTan();
     223                 :            : };
     224                 :            : 
     225                 :            : Polygon Rect2Poly(const Rectangle& rRect, const GeoStat& rGeo);
     226                 :            : void Poly2Rect(const Polygon& rPol, Rectangle& rRect, GeoStat& rGeo);
     227                 :            : 
     228                 :            : SVX_DLLPUBLIC void OrthoDistance8(const Point& rPt0, Point& rPt, bool bBigOrtho);
     229                 :            : SVX_DLLPUBLIC void OrthoDistance4(const Point& rPt0, Point& rPt, bool bBigOrtho);
     230                 :            : 
     231                 :            : // Multiplikation und anschliessende Division.
     232                 :            : // Rechnung und Zwischenergebnis sind BigInt.
     233                 :            : SVX_DLLPUBLIC long BigMulDiv(long nVal, long nMul, long nDiv);
     234                 :            : 
     235                 :            : // Fehlerbehaftetes Kuerzen einer Fraction.
     236                 :            : // nDigits gibt an, wieviele signifikante Stellen in
     237                 :            : // Zaehler/Nenner mindestens erhalten bleiben sollen.
     238                 :            : void Kuerzen(Fraction& rF, unsigned nDigits);
     239                 :            : 
     240                 :            : 
     241                 :        314 : class FrPair {
     242                 :            :     Fraction aX;
     243                 :            :     Fraction aY;
     244                 :            : public:
     245                 :            :     FrPair()                                          : aX(0,1),aY(0,1)             {}
     246                 :          0 :     FrPair(const Fraction& rBoth)                     : aX(rBoth),aY(rBoth)         {}
     247                 :        314 :     FrPair(const Fraction& rX, const Fraction& rY)    : aX(rX),aY(rY)               {}
     248                 :        628 :     FrPair(long nMul, long nDiv)                      : aX(nMul,nDiv),aY(nMul,nDiv) {}
     249                 :         91 :     FrPair(long xMul, long xDiv, long yMul, long yDiv): aX(xMul,xDiv),aY(yMul,yDiv) {}
     250                 :            :     const Fraction& X() const { return aX; }
     251                 :            :     const Fraction& Y() const { return aY; }
     252                 :        858 :     Fraction& X()             { return aX; }
     253                 :        858 :     Fraction& Y()             { return aY; }
     254                 :            : };
     255                 :            : 
     256                 :            : // Fuer die Umrechnung von Masseinheiten
     257                 :            : SVX_DLLPUBLIC FrPair GetMapFactor(MapUnit eS, MapUnit eD);
     258                 :            : FrPair GetMapFactor(FieldUnit eS, FieldUnit eD);
     259                 :            : 
     260                 :       4892 : inline bool IsMetric(MapUnit eU) {
     261 [ +  + ][ +  - ]:       4892 :     return (eU==MAP_100TH_MM || eU==MAP_10TH_MM || eU==MAP_MM || eU==MAP_CM);
         [ +  - ][ -  + ]
     262                 :            : }
     263                 :            : 
     264                 :       5520 : inline bool IsInch(MapUnit eU) {
     265                 :            :     return (eU==MAP_1000TH_INCH || eU==MAP_100TH_INCH || eU==MAP_10TH_INCH || eU==MAP_INCH ||
     266 [ +  - ][ +  - ]:       5520 :             eU==MAP_POINT       || eU==MAP_TWIP);
         [ +  - ][ +  + ]
         [ +  + ][ +  + ]
     267                 :            : }
     268                 :            : 
     269                 :       4892 : inline bool IsMetric(FieldUnit eU) {
     270 [ +  + ][ +  - ]:       4892 :     return (eU==FUNIT_MM || eU==FUNIT_CM || eU==FUNIT_M || eU==FUNIT_KM || eU==FUNIT_100TH_MM);
         [ +  - ][ +  - ]
                 [ -  + ]
     271                 :            : }
     272                 :            : 
     273                 :       4892 : inline bool IsInch(FieldUnit eU) {
     274                 :            :     return (eU==FUNIT_TWIP || eU==FUNIT_POINT || eU==FUNIT_PICA ||
     275 [ +  - ][ +  - ]:       4892 :             eU==FUNIT_INCH || eU==FUNIT_FOOT || eU==FUNIT_MILE);
         [ +  - ][ +  + ]
         [ +  - ][ -  + ]
     276                 :            : }
     277                 :            : 
     278                 :            : class SVX_DLLPUBLIC SdrFormatter {
     279                 :            :     Fraction  aScale;
     280                 :            :     long      nMul_;
     281                 :            :     long      nDiv_;
     282                 :            :     short     nKomma_;
     283                 :            :     bool      bSrcFU;
     284                 :            :     bool      bDstFU;
     285                 :            :     bool      bDirty;
     286                 :            :     MapUnit   eSrcMU;
     287                 :            :     MapUnit   eDstMU;
     288                 :            :     FieldUnit eSrcFU;
     289                 :            :     FieldUnit eDstFU;
     290                 :            : private:
     291                 :            :     SVX_DLLPRIVATE void Undirty();
     292         [ #  # ]:          0 :     SVX_DLLPRIVATE void ForceUndirty() const { if (bDirty) ((SdrFormatter*)this)->Undirty(); }
     293                 :            : public:
     294                 :          0 :     SdrFormatter(MapUnit eSrc, MapUnit eDst)     { eSrcMU=eSrc; bSrcFU=sal_False; eDstMU=eDst; bDstFU=sal_False; bDirty=sal_True; }
     295                 :            :     SdrFormatter(MapUnit eSrc, FieldUnit eDst)   { eSrcMU=eSrc; bSrcFU=sal_False; eDstFU=eDst; bDstFU=sal_True;  bDirty=sal_True; }
     296                 :            :     SdrFormatter(FieldUnit eSrc, MapUnit eDst)   { eSrcFU=eSrc; bSrcFU=sal_True;  eDstMU=eDst; bDstFU=sal_False; bDirty=sal_True; }
     297                 :            :     SdrFormatter(FieldUnit eSrc, FieldUnit eDst) { eSrcFU=eSrc; bSrcFU=sal_True;  eDstFU=eDst; bDstFU=sal_True;  bDirty=sal_True; }
     298                 :            :     void SetSourceUnit(MapUnit eSrc)        { eSrcMU=eSrc; bSrcFU=sal_False; bDirty=sal_True; }
     299                 :            :     void SetSourceUnit(FieldUnit eSrc)      { eSrcFU=eSrc; bSrcFU=sal_True;  bDirty=sal_True; }
     300                 :            :     void SetDestinationUnit(MapUnit eDst)   { eDstMU=eDst; bDstFU=sal_False; bDirty=sal_True; }
     301                 :            :     void SetDestinationUnit(FieldUnit eDst) { eDstFU=eDst; bDstFU=sal_True;  bDirty=sal_True; }
     302                 :            :     void TakeStr(long nVal, XubString& rStr) const;
     303                 :            :     static void TakeUnitStr(MapUnit eUnit, XubString& rStr);
     304                 :            :     static void TakeUnitStr(FieldUnit eUnit, XubString& rStr);
     305                 :            :     static XubString GetUnitStr(MapUnit eUnit)   { XubString aStr; TakeUnitStr(eUnit,aStr); return aStr; }
     306         [ #  # ]:          0 :     static XubString GetUnitStr(FieldUnit eUnit) { XubString aStr; TakeUnitStr(eUnit,aStr); return aStr; }
     307                 :            : };
     308                 :            : 
     309                 :            : ////////////////////////////////////////////////////////////////////////////////////////////////////
     310                 :            : 
     311                 :            : #endif //_SVDTRANS_HXX
     312                 :            : 
     313                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10