fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / include / svx / svdtrans.hxx
blobc86fd0d35582504409631893e76c0bd13675c3f5
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 _SVDTRANS_HXX
21 #define _SVDTRANS_HXX
23 #include <tools/gen.hxx>
24 #include <tools/poly.hxx>
25 #include <tools/fract.hxx>
27 #include <vcl/mapmod.hxx>
28 #include <tools/string.hxx>
29 #include "svx/svxdllapi.h"
31 #include <vcl/field.hxx>
33 ////////////////////////////////////////////////////////////////////////////////////////////////////
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
46 // Der maximale Shearwinkel
47 #define SDRMAXSHEAR 8900
49 class XPolygon;
50 class XPolyPolygon;
52 inline long Round(double a) { return a>0.0 ? (long)(a+0.5) : -(long)((-a)+0.5); }
54 inline void MoveRect(Rectangle& rRect, const Size& S) { rRect.Move(S.Width(),S.Height()); }
55 inline void MovePoint(Point& rPnt, const Size& S) { rPnt.X()+=S.Width(); rPnt.Y()+=S.Height(); }
56 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);
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);
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);
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);
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);
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);
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);
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);
103 /**************************************************************************************************/
104 /* Inline */
105 /**************************************************************************************************/
107 inline void ResizePoint(Point& rPnt, const Point& rRef, Fraction xFact, Fraction yFact)
109 if (xFact.GetDenominator()==0) xFact=Fraction(xFact.GetNumerator(),1); // DivZero abfangen
110 if (yFact.GetDenominator()==0) yFact=Fraction(yFact.GetNumerator(),1); // DivZero abfangen
111 rPnt.X()=rRef.X()+ Round(((double)(rPnt.X()-rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
112 rPnt.Y()=rRef.Y()+ Round(((double)(rPnt.Y()-rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
115 inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs)
117 long dx=rPnt.X()-rRef.X();
118 long dy=rPnt.Y()-rRef.Y();
119 rPnt.X()=Round(rRef.X()+dx*cs+dy*sn);
120 rPnt.Y()=Round(rRef.Y()+dy*cs-dx*sn);
123 inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear)
125 if (!bVShear) { // Horizontal
126 if (rPnt.Y()!=rRef.Y()) { // sonst nicht noetig
127 rPnt.X()-=Round((rPnt.Y()-rRef.Y())*tn);
129 } else { // ansonsten vertikal
130 if (rPnt.X()!=rRef.X()) { // sonst nicht noetig
131 rPnt.Y()-=Round((rPnt.X()-rRef.X())*tn);
136 inline double GetCrookAngle(Point& rPnt, const Point& rCenter, const Point& rRad, bool bVertical)
138 double nWink;
139 if (bVertical) {
140 long dy=rPnt.Y()-rCenter.Y();
141 nWink=(double)dy/(double)rRad.Y();
142 rPnt.Y()=rCenter.Y();
143 } else {
144 long dx=rCenter.X()-rPnt.X();
145 nWink=(double)dx/(double)rRad.X();
146 rPnt.X()=rCenter.X();
148 return nWink;
151 /**************************************************************************************************/
152 /**************************************************************************************************/
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);
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.
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 GeoStat(): nDrehWink(0),nShearWink(0),nTan(0.0),nSin(0.0),nCos(1.0),bMirrored(false) {}
212 void RecalcSinCos();
213 void RecalcTan();
216 Polygon Rect2Poly(const Rectangle& rRect, const GeoStat& rGeo);
217 void Poly2Rect(const Polygon& rPol, Rectangle& rRect, GeoStat& rGeo);
219 SVX_DLLPUBLIC void OrthoDistance8(const Point& rPt0, Point& rPt, bool bBigOrtho);
220 SVX_DLLPUBLIC void OrthoDistance4(const Point& rPt0, Point& rPt, bool bBigOrtho);
222 // Multiplikation und anschliessende Division.
223 // Rechnung und Zwischenergebnis sind BigInt.
224 SVX_DLLPUBLIC long BigMulDiv(long nVal, long nMul, long nDiv);
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);
232 class FrPair {
233 Fraction aX;
234 Fraction aY;
235 public:
236 FrPair() : aX(0,1),aY(0,1) {}
237 FrPair(const Fraction& rBoth) : aX(rBoth),aY(rBoth) {}
238 FrPair(const Fraction& rX, const Fraction& rY) : aX(rX),aY(rY) {}
239 FrPair(long nMul, long nDiv) : aX(nMul,nDiv),aY(nMul,nDiv) {}
240 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 Fraction& X() { return aX; }
244 Fraction& Y() { return aY; }
247 // Fuer die Umrechnung von Masseinheiten
248 SVX_DLLPUBLIC FrPair GetMapFactor(MapUnit eS, MapUnit eD);
249 FrPair GetMapFactor(FieldUnit eS, FieldUnit eD);
251 inline bool IsMetric(MapUnit eU) {
252 return (eU==MAP_100TH_MM || eU==MAP_10TH_MM || eU==MAP_MM || eU==MAP_CM);
255 inline bool IsInch(MapUnit eU) {
256 return (eU==MAP_1000TH_INCH || eU==MAP_100TH_INCH || eU==MAP_10TH_INCH || eU==MAP_INCH ||
257 eU==MAP_POINT || eU==MAP_TWIP);
260 inline bool IsMetric(FieldUnit eU) {
261 return (eU==FUNIT_MM || eU==FUNIT_CM || eU==FUNIT_M || eU==FUNIT_KM || eU==FUNIT_100TH_MM);
264 inline bool IsInch(FieldUnit eU) {
265 return (eU==FUNIT_TWIP || eU==FUNIT_POINT || eU==FUNIT_PICA ||
266 eU==FUNIT_INCH || eU==FUNIT_FOOT || eU==FUNIT_MILE);
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 SVX_DLLPRIVATE void ForceUndirty() const { if (bDirty) ((SdrFormatter*)this)->Undirty(); }
284 public:
285 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 static OUString GetUnitStr(FieldUnit eUnit) { OUString aStr; TakeUnitStr(eUnit,aStr); return aStr; }
300 ////////////////////////////////////////////////////////////////////////////////////////////////////
302 #endif //_SVDTRANS_HXX
304 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */