bump product version to 4.2.0.1
[LibreOffice.git] / include / svx / svdtrans.hxx
blobda234a7971c1682c67d6577747e07d4771cf52a6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SVX_SVDTRANS_HXX
21 #define INCLUDED_SVX_SVDTRANS_HXX
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>
31 ////////////////////////////////////////////////////////////////////////////////////////////////////
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
44 // Der maximale Shearwinkel
45 #define SDRMAXSHEAR 8900
47 class XPolygon;
48 class XPolyPolygon;
50 inline long Round(double a) { return a>0.0 ? (long)(a+0.5) : -(long)((-a)+0.5); }
52 inline void MoveRect(Rectangle& rRect, const Size& S) { rRect.Move(S.Width(),S.Height()); }
53 inline void MovePoint(Point& rPnt, const Size& S) { rPnt.X()+=S.Width(); rPnt.Y()+=S.Height(); }
54 inline void MovePoly(Polygon& rPoly, const Size& S) { rPoly.Move(S.Width(),S.Height()); }
55 inline void MovePoly(PolyPolygon& rPoly, const Size& S) { rPoly.Move(S.Width(),S.Height()); }
56 void MoveXPoly(XPolygon& rPoly, const Size& S);
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);
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);
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);
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);
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);
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);
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);
101 /**************************************************************************************************/
102 /* Inline */
103 /**************************************************************************************************/
105 inline void ResizePoint(Point& rPnt, const Point& rRef, Fraction xFact, Fraction yFact)
107 if (xFact.GetDenominator()==0) xFact=Fraction(xFact.GetNumerator(),1); // DivZero abfangen
108 if (yFact.GetDenominator()==0) yFact=Fraction(yFact.GetNumerator(),1); // DivZero abfangen
109 rPnt.X()=rRef.X()+ Round(((double)(rPnt.X()-rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
110 rPnt.Y()=rRef.Y()+ Round(((double)(rPnt.Y()-rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
113 inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs)
115 long dx=rPnt.X()-rRef.X();
116 long dy=rPnt.Y()-rRef.Y();
117 rPnt.X()=Round(rRef.X()+dx*cs+dy*sn);
118 rPnt.Y()=Round(rRef.Y()+dy*cs-dx*sn);
121 inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear)
123 if (!bVShear) { // Horizontal
124 if (rPnt.Y()!=rRef.Y()) { // sonst nicht noetig
125 rPnt.X()-=Round((rPnt.Y()-rRef.Y())*tn);
127 } else { // ansonsten vertikal
128 if (rPnt.X()!=rRef.X()) { // sonst nicht noetig
129 rPnt.Y()-=Round((rPnt.X()-rRef.X())*tn);
134 inline double GetCrookAngle(Point& rPnt, const Point& rCenter, const Point& rRad, bool bVertical)
136 double nWink;
137 if (bVertical) {
138 long dy=rPnt.Y()-rCenter.Y();
139 nWink=(double)dy/(double)rRad.Y();
140 rPnt.Y()=rCenter.Y();
141 } else {
142 long dx=rCenter.X()-rPnt.X();
143 nWink=(double)dx/(double)rRad.X();
144 rPnt.X()=rCenter.X();
146 return nWink;
149 /**************************************************************************************************/
150 /**************************************************************************************************/
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);
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.
200 class GeoStat { // Geometrischer Status fuer ein Rect
201 public:
202 long nDrehWink;
203 long nShearWink;
204 double nTan; // tan(nShearWink)
205 double nSin; // sin(nDrehWink)
206 double nCos; // cos(nDrehWink)
207 bool bMirrored; // Horizontal gespiegelt? (ni)
208 public:
209 GeoStat(): nDrehWink(0),nShearWink(0),nTan(0.0),nSin(0.0),nCos(1.0),bMirrored(false) {}
210 void RecalcSinCos();
211 void RecalcTan();
214 Polygon Rect2Poly(const Rectangle& rRect, const GeoStat& rGeo);
215 void Poly2Rect(const Polygon& rPol, Rectangle& rRect, GeoStat& rGeo);
217 SVX_DLLPUBLIC void OrthoDistance8(const Point& rPt0, Point& rPt, bool bBigOrtho);
218 SVX_DLLPUBLIC void OrthoDistance4(const Point& rPt0, Point& rPt, bool bBigOrtho);
220 // Multiplikation und anschliessende Division.
221 // Rechnung und Zwischenergebnis sind BigInt.
222 SVX_DLLPUBLIC long BigMulDiv(long nVal, long nMul, long nDiv);
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);
230 class FrPair {
231 Fraction aX;
232 Fraction aY;
233 public:
234 FrPair() : aX(0,1),aY(0,1) {}
235 FrPair(const Fraction& rBoth) : aX(rBoth),aY(rBoth) {}
236 FrPair(const Fraction& rX, const Fraction& rY) : aX(rX),aY(rY) {}
237 FrPair(long nMul, long nDiv) : aX(nMul,nDiv),aY(nMul,nDiv) {}
238 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 Fraction& X() { return aX; }
242 Fraction& Y() { return aY; }
245 // Fuer die Umrechnung von Masseinheiten
246 SVX_DLLPUBLIC FrPair GetMapFactor(MapUnit eS, MapUnit eD);
247 FrPair GetMapFactor(FieldUnit eS, FieldUnit eD);
249 inline bool IsMetric(MapUnit eU) {
250 return (eU==MAP_100TH_MM || eU==MAP_10TH_MM || eU==MAP_MM || eU==MAP_CM);
253 inline bool IsInch(MapUnit eU) {
254 return (eU==MAP_1000TH_INCH || eU==MAP_100TH_INCH || eU==MAP_10TH_INCH || eU==MAP_INCH ||
255 eU==MAP_POINT || eU==MAP_TWIP);
258 inline bool IsMetric(FieldUnit eU) {
259 return (eU==FUNIT_MM || eU==FUNIT_CM || eU==FUNIT_M || eU==FUNIT_KM || eU==FUNIT_100TH_MM);
262 inline bool IsInch(FieldUnit eU) {
263 return (eU==FUNIT_TWIP || eU==FUNIT_POINT || eU==FUNIT_PICA ||
264 eU==FUNIT_INCH || eU==FUNIT_FOOT || eU==FUNIT_MILE);
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 SVX_DLLPRIVATE void ForceUndirty() const { if (bDirty) ((SdrFormatter*)this)->Undirty(); }
282 public:
283 SdrFormatter(MapUnit eSrc, MapUnit eDst) { eSrcMU=eSrc; bSrcFU=sal_False; eDstMU=eDst; bDstFU=sal_False; bDirty=sal_True; }
284 SdrFormatter(MapUnit eSrc, FieldUnit eDst) { eSrcMU=eSrc; bSrcFU=sal_False; eDstFU=eDst; bDstFU=sal_True; bDirty=sal_True; }
285 SdrFormatter(FieldUnit eSrc, MapUnit eDst) { eSrcFU=eSrc; bSrcFU=sal_True; eDstMU=eDst; bDstFU=sal_False; bDirty=sal_True; }
286 SdrFormatter(FieldUnit eSrc, FieldUnit eDst) { eSrcFU=eSrc; bSrcFU=sal_True; eDstFU=eDst; bDstFU=sal_True; bDirty=sal_True; }
287 void SetSourceUnit(MapUnit eSrc) { eSrcMU=eSrc; bSrcFU=sal_False; bDirty=sal_True; }
288 void SetSourceUnit(FieldUnit eSrc) { eSrcFU=eSrc; bSrcFU=sal_True; bDirty=sal_True; }
289 void SetDestinationUnit(MapUnit eDst) { eDstMU=eDst; bDstFU=sal_False; bDirty=sal_True; }
290 void SetDestinationUnit(FieldUnit eDst) { eDstFU=eDst; bDstFU=sal_True; bDirty=sal_True; }
291 void TakeStr(long nVal, OUString& rStr) const;
292 static void TakeUnitStr(MapUnit eUnit, OUString& rStr);
293 static void TakeUnitStr(FieldUnit eUnit, OUString& rStr);
294 static OUString GetUnitStr(MapUnit eUnit) { OUString aStr; TakeUnitStr(eUnit,aStr); return aStr; }
295 static OUString GetUnitStr(FieldUnit eUnit) { OUString aStr; TakeUnitStr(eUnit,aStr); return aStr; }
298 ////////////////////////////////////////////////////////////////////////////////////////////////////
300 #endif // INCLUDED_SVX_SVDTRANS_HXX
302 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */