LCOV - code coverage report
Current view: top level - include/svx - svdtrans.hxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 40 57 70.2 %
Date: 2015-06-13 12:38:46 Functions: 19 24 79.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11