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

Generated by: LCOV version 1.10