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

Generated by: LCOV version 1.10