xref: /AOO41X/main/svx/source/svdraw/svdtrans.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <svx/svdtrans.hxx>
32*cdf0e10cSrcweir #include <math.h>
33*cdf0e10cSrcweir #include <svx/xpoly.hxx>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <vcl/virdev.hxx>
36*cdf0e10cSrcweir #include <tools/bigint.hxx>
37*cdf0e10cSrcweir #include <tools/debug.hxx>
38*cdf0e10cSrcweir #include <unotools/syslocale.hxx>
39*cdf0e10cSrcweir 
40*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir void MoveXPoly(XPolygon& rPoly, const Size& S)
43*cdf0e10cSrcweir {
44*cdf0e10cSrcweir 	rPoly.Move(S.Width(),S.Height());
45*cdf0e10cSrcweir }
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir void MoveXPoly(XPolyPolygon& rPoly, const Size& S)
48*cdf0e10cSrcweir {
49*cdf0e10cSrcweir 	rPoly.Move(S.Width(),S.Height());
50*cdf0e10cSrcweir }
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir void ResizeRect(Rectangle& rRect, const Point& rRef, const Fraction& rxFact, const Fraction& ryFact, FASTBOOL bNoJustify)
55*cdf0e10cSrcweir {
56*cdf0e10cSrcweir 	Fraction xFact(rxFact);
57*cdf0e10cSrcweir 	Fraction yFact(ryFact);
58*cdf0e10cSrcweir 	//long nHgt=rRect.Bottom()-rRect.Top();
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir 	{
61*cdf0e10cSrcweir 		if (xFact.GetDenominator()==0) {
62*cdf0e10cSrcweir 			long nWdt=rRect.Right()-rRect.Left();
63*cdf0e10cSrcweir 			if (xFact.GetNumerator()>=0) { // DivZero abfangen
64*cdf0e10cSrcweir 				xFact=Fraction(xFact.GetNumerator(),1);
65*cdf0e10cSrcweir 				if (nWdt==0) rRect.Right()++;
66*cdf0e10cSrcweir 			} else {
67*cdf0e10cSrcweir 				xFact=Fraction(xFact.GetNumerator(),-1);
68*cdf0e10cSrcweir 				if (nWdt==0) rRect.Left()--;
69*cdf0e10cSrcweir 			}
70*cdf0e10cSrcweir 		}
71*cdf0e10cSrcweir 		rRect.Left()  =rRef.X()+Round(((double)(rRect.Left()  -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
72*cdf0e10cSrcweir 		rRect.Right() =rRef.X()+Round(((double)(rRect.Right() -rRef.X())*xFact.GetNumerator())/xFact.GetDenominator());
73*cdf0e10cSrcweir 	}
74*cdf0e10cSrcweir 	{
75*cdf0e10cSrcweir 		if (yFact.GetDenominator()==0) {
76*cdf0e10cSrcweir 			long nHgt=rRect.Bottom()-rRect.Top();
77*cdf0e10cSrcweir 			if (yFact.GetNumerator()>=0) { // DivZero abfangen
78*cdf0e10cSrcweir 				yFact=Fraction(yFact.GetNumerator(),1);
79*cdf0e10cSrcweir 				if (nHgt==0) rRect.Bottom()++;
80*cdf0e10cSrcweir 			} else {
81*cdf0e10cSrcweir 				yFact=Fraction(yFact.GetNumerator(),-1);
82*cdf0e10cSrcweir 				if (nHgt==0) rRect.Top()--;
83*cdf0e10cSrcweir 			}
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir 			yFact=Fraction(yFact.GetNumerator(),1); // DivZero abfangen
86*cdf0e10cSrcweir 		}
87*cdf0e10cSrcweir 		rRect.Top()   =rRef.Y()+Round(((double)(rRect.Top()   -rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
88*cdf0e10cSrcweir 		rRect.Bottom()=rRef.Y()+Round(((double)(rRect.Bottom()-rRef.Y())*yFact.GetNumerator())/yFact.GetDenominator());
89*cdf0e10cSrcweir 	}
90*cdf0e10cSrcweir 	if (!bNoJustify) rRect.Justify();
91*cdf0e10cSrcweir }
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir void ResizePoly(Polygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
95*cdf0e10cSrcweir {
96*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetSize();
97*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
98*cdf0e10cSrcweir 		ResizePoint(rPoly[i],rRef,xFact,yFact);
99*cdf0e10cSrcweir 	}
100*cdf0e10cSrcweir }
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
103*cdf0e10cSrcweir {
104*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetPointCount();
105*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
106*cdf0e10cSrcweir 		ResizePoint(rPoly[i],rRef,xFact,yFact);
107*cdf0e10cSrcweir 	}
108*cdf0e10cSrcweir }
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir void ResizePoly(PolyPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
111*cdf0e10cSrcweir {
112*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
113*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
114*cdf0e10cSrcweir 		ResizePoly(rPoly[i],rRef,xFact,yFact);
115*cdf0e10cSrcweir 	}
116*cdf0e10cSrcweir }
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir void ResizeXPoly(XPolyPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact)
119*cdf0e10cSrcweir {
120*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
121*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
122*cdf0e10cSrcweir 		ResizeXPoly(rPoly[i],rRef,xFact,yFact);
123*cdf0e10cSrcweir 	}
124*cdf0e10cSrcweir }
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir void RotatePoly(Polygon& rPoly, const Point& rRef, double sn, double cs)
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetSize();
131*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
132*cdf0e10cSrcweir 		RotatePoint(rPoly[i],rRef,sn,cs);
133*cdf0e10cSrcweir 	}
134*cdf0e10cSrcweir }
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir void RotateXPoly(XPolygon& rPoly, const Point& rRef, double sn, double cs)
137*cdf0e10cSrcweir {
138*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetPointCount();
139*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
140*cdf0e10cSrcweir 		RotatePoint(rPoly[i],rRef,sn,cs);
141*cdf0e10cSrcweir 	}
142*cdf0e10cSrcweir }
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir void RotatePoly(PolyPolygon& rPoly, const Point& rRef, double sn, double cs)
145*cdf0e10cSrcweir {
146*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
147*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
148*cdf0e10cSrcweir 		RotatePoly(rPoly[i],rRef,sn,cs);
149*cdf0e10cSrcweir 	}
150*cdf0e10cSrcweir }
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir void RotateXPoly(XPolyPolygon& rPoly, const Point& rRef, double sn, double cs)
153*cdf0e10cSrcweir {
154*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
155*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
156*cdf0e10cSrcweir 		RotateXPoly(rPoly[i],rRef,sn,cs);
157*cdf0e10cSrcweir 	}
158*cdf0e10cSrcweir }
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir void MirrorRect(Rectangle& rRect, const Point& /*rRef1*/, const Point& /*rRef2*/, FASTBOOL bNoJustify)
163*cdf0e10cSrcweir {
164*cdf0e10cSrcweir 	// !!! fehlende Implementation !!!
165*cdf0e10cSrcweir 	if (!bNoJustify) rRect.Justify();
166*cdf0e10cSrcweir }
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir void MirrorPoint(Point& rPnt, const Point& rRef1, const Point& rRef2)
169*cdf0e10cSrcweir {
170*cdf0e10cSrcweir 	long mx=rRef2.X()-rRef1.X();
171*cdf0e10cSrcweir 	long my=rRef2.Y()-rRef1.Y();
172*cdf0e10cSrcweir 	if (mx==0) { // Achse senkrecht
173*cdf0e10cSrcweir 		long dx=rRef1.X()-rPnt.X();
174*cdf0e10cSrcweir 		rPnt.X()+=2*dx;
175*cdf0e10cSrcweir 	} else if (my==0) { // Achse waagerecht
176*cdf0e10cSrcweir 		long dy=rRef1.Y()-rPnt.Y();
177*cdf0e10cSrcweir 		rPnt.Y()+=2*dy;
178*cdf0e10cSrcweir 	} else if (mx==my) { // Achse diagonal '\'
179*cdf0e10cSrcweir 		long dx1=rPnt.X()-rRef1.X();
180*cdf0e10cSrcweir 		long dy1=rPnt.Y()-rRef1.Y();
181*cdf0e10cSrcweir 		rPnt.X()=rRef1.X()+dy1;
182*cdf0e10cSrcweir 		rPnt.Y()=rRef1.Y()+dx1;
183*cdf0e10cSrcweir 	} else if (mx==-my) { // Achse diagonal '/'
184*cdf0e10cSrcweir 		long dx1=rPnt.X()-rRef1.X();
185*cdf0e10cSrcweir 		long dy1=rPnt.Y()-rRef1.Y();
186*cdf0e10cSrcweir 		rPnt.X()=rRef1.X()-dy1;
187*cdf0e10cSrcweir 		rPnt.Y()=rRef1.Y()-dx1;
188*cdf0e10cSrcweir 	} else { // beliebige Achse
189*cdf0e10cSrcweir 		// mal optimieren !!!
190*cdf0e10cSrcweir 		// Lot auf der Spiegelachse faellen oder so
191*cdf0e10cSrcweir 		long nRefWink=GetAngle(rRef2-rRef1);
192*cdf0e10cSrcweir 		rPnt-=rRef1;
193*cdf0e10cSrcweir 		long nPntWink=GetAngle(rPnt);
194*cdf0e10cSrcweir 		long nWink=2*(nRefWink-nPntWink);
195*cdf0e10cSrcweir 		double a=nWink*nPi180;
196*cdf0e10cSrcweir 		double nSin=sin(a);
197*cdf0e10cSrcweir 		double nCos=cos(a);
198*cdf0e10cSrcweir 		RotatePoint(rPnt,Point(),nSin,nCos);
199*cdf0e10cSrcweir 		rPnt+=rRef1;
200*cdf0e10cSrcweir 	}
201*cdf0e10cSrcweir }
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir void MirrorPoly(Polygon& rPoly, const Point& rRef1, const Point& rRef2)
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetSize();
206*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
207*cdf0e10cSrcweir 		MirrorPoint(rPoly[i],rRef1,rRef2);
208*cdf0e10cSrcweir 	}
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir void MirrorXPoly(XPolygon& rPoly, const Point& rRef1, const Point& rRef2)
212*cdf0e10cSrcweir {
213*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetPointCount();
214*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
215*cdf0e10cSrcweir 		MirrorPoint(rPoly[i],rRef1,rRef2);
216*cdf0e10cSrcweir 	}
217*cdf0e10cSrcweir }
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir void MirrorPoly(PolyPolygon& rPoly, const Point& rRef1, const Point& rRef2)
220*cdf0e10cSrcweir {
221*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
222*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
223*cdf0e10cSrcweir 		MirrorPoly(rPoly[i],rRef1,rRef2);
224*cdf0e10cSrcweir 	}
225*cdf0e10cSrcweir }
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir void MirrorXPoly(XPolyPolygon& rPoly, const Point& rRef1, const Point& rRef2)
228*cdf0e10cSrcweir {
229*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
230*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
231*cdf0e10cSrcweir 		MirrorXPoly(rPoly[i],rRef1,rRef2);
232*cdf0e10cSrcweir 	}
233*cdf0e10cSrcweir }
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir void ShearPoly(Polygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
238*cdf0e10cSrcweir {
239*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetSize();
240*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
241*cdf0e10cSrcweir 		ShearPoint(rPoly[i],rRef,tn,bVShear);
242*cdf0e10cSrcweir 	}
243*cdf0e10cSrcweir }
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir void ShearXPoly(XPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.GetPointCount();
248*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
249*cdf0e10cSrcweir 		ShearPoint(rPoly[i],rRef,tn,bVShear);
250*cdf0e10cSrcweir 	}
251*cdf0e10cSrcweir }
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir void ShearPoly(PolyPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
254*cdf0e10cSrcweir {
255*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
256*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
257*cdf0e10cSrcweir 		ShearPoly(rPoly[i],rRef,tn,bVShear);
258*cdf0e10cSrcweir 	}
259*cdf0e10cSrcweir }
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir void ShearXPoly(XPolyPolygon& rPoly, const Point& rRef, double tn, FASTBOOL bVShear)
262*cdf0e10cSrcweir {
263*cdf0e10cSrcweir 	sal_uInt16 nAnz=rPoly.Count();
264*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<nAnz; i++) {
265*cdf0e10cSrcweir 		ShearXPoly(rPoly[i],rRef,tn,bVShear);
266*cdf0e10cSrcweir 	}
267*cdf0e10cSrcweir }
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
270*cdf0e10cSrcweir //
271*cdf0e10cSrcweir //   @@@@  @@@@@   @@@@   @@@@  @@  @@
272*cdf0e10cSrcweir //  @@  @@ @@  @@ @@  @@ @@  @@ @@  @@
273*cdf0e10cSrcweir //  @@     @@  @@ @@  @@ @@  @@ @@ @@
274*cdf0e10cSrcweir //  @@     @@@@@  @@  @@ @@  @@ @@@@
275*cdf0e10cSrcweir //  @@     @@  @@ @@  @@ @@  @@ @@ @@
276*cdf0e10cSrcweir //  @@  @@ @@  @@ @@  @@ @@  @@ @@  @@
277*cdf0e10cSrcweir //   @@@@  @@  @@  @@@@   @@@@  @@  @@
278*cdf0e10cSrcweir //
279*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
282*cdf0e10cSrcweir 						 const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert)
283*cdf0e10cSrcweir {
284*cdf0e10cSrcweir 	FASTBOOL bC1=pC1!=NULL;
285*cdf0e10cSrcweir 	FASTBOOL bC2=pC2!=NULL;
286*cdf0e10cSrcweir 	long x0=rPnt.X();
287*cdf0e10cSrcweir 	long y0=rPnt.Y();
288*cdf0e10cSrcweir 	long cx=rCenter.X();
289*cdf0e10cSrcweir 	long cy=rCenter.Y();
290*cdf0e10cSrcweir 	double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
291*cdf0e10cSrcweir 	double sn=sin(nWink);
292*cdf0e10cSrcweir 	double cs=cos(nWink);
293*cdf0e10cSrcweir 	RotatePoint(rPnt,rCenter,sn,cs);
294*cdf0e10cSrcweir 	if (bC1) {
295*cdf0e10cSrcweir 		if (bVert) {
296*cdf0e10cSrcweir 			// Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
297*cdf0e10cSrcweir 			pC1->Y()-=y0;
298*cdf0e10cSrcweir 			// Resize, entsprechend der Entfernung vom Zentrum
299*cdf0e10cSrcweir 			pC1->Y()=Round(((double)pC1->Y()) /rRad.X()*(cx-pC1->X()));
300*cdf0e10cSrcweir 			pC1->Y()+=cy;
301*cdf0e10cSrcweir 		} else {
302*cdf0e10cSrcweir 			// Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
303*cdf0e10cSrcweir 			pC1->X()-=x0;
304*cdf0e10cSrcweir 			// Resize, entsprechend der Entfernung vom Zentrum
305*cdf0e10cSrcweir 			long nPntRad=cy-pC1->Y();
306*cdf0e10cSrcweir 			double nFact=(double)nPntRad/(double)rRad.Y();
307*cdf0e10cSrcweir 			pC1->X()=Round((double)pC1->X()*nFact);
308*cdf0e10cSrcweir 			pC1->X()+=cx;
309*cdf0e10cSrcweir 		}
310*cdf0e10cSrcweir 		RotatePoint(*pC1,rCenter,sn,cs);
311*cdf0e10cSrcweir 	}
312*cdf0e10cSrcweir 	if (bC2) {
313*cdf0e10cSrcweir 		if (bVert) {
314*cdf0e10cSrcweir 			// Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
315*cdf0e10cSrcweir 			pC2->Y()-=y0;
316*cdf0e10cSrcweir 			// Resize, entsprechend der Entfernung vom Zentrum
317*cdf0e10cSrcweir 			pC2->Y()=Round(((double)pC2->Y()) /rRad.X()*(rCenter.X()-pC2->X()));
318*cdf0e10cSrcweir 			pC2->Y()+=cy;
319*cdf0e10cSrcweir 		} else {
320*cdf0e10cSrcweir 			// Richtung Zentrum verschieben, als Ausgangsposition fuer Rotate
321*cdf0e10cSrcweir 			pC2->X()-=x0;
322*cdf0e10cSrcweir 			// Resize, entsprechend der Entfernung vom Zentrum
323*cdf0e10cSrcweir 			long nPntRad=rCenter.Y()-pC2->Y();
324*cdf0e10cSrcweir 			double nFact=(double)nPntRad/(double)rRad.Y();
325*cdf0e10cSrcweir 			pC2->X()=Round((double)pC2->X()*nFact);
326*cdf0e10cSrcweir 			pC2->X()+=cx;
327*cdf0e10cSrcweir 		}
328*cdf0e10cSrcweir 		RotatePoint(*pC2,rCenter,sn,cs);
329*cdf0e10cSrcweir 	}
330*cdf0e10cSrcweir 	rSin=sn;
331*cdf0e10cSrcweir 	rCos=cs;
332*cdf0e10cSrcweir 	return nWink;
333*cdf0e10cSrcweir }
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir double CrookSlantXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
336*cdf0e10cSrcweir 						const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert)
337*cdf0e10cSrcweir {
338*cdf0e10cSrcweir 	FASTBOOL bC1=pC1!=NULL;
339*cdf0e10cSrcweir 	FASTBOOL bC2=pC2!=NULL;
340*cdf0e10cSrcweir 	long x0=rPnt.X();
341*cdf0e10cSrcweir 	long y0=rPnt.Y();
342*cdf0e10cSrcweir 	long dx1=0,dy1=0;
343*cdf0e10cSrcweir 	long dxC1=0,dyC1=0;
344*cdf0e10cSrcweir 	long dxC2=0,dyC2=0;
345*cdf0e10cSrcweir 	if (bVert) {
346*cdf0e10cSrcweir 		long nStart=rCenter.X()-rRad.X();
347*cdf0e10cSrcweir 		dx1=rPnt.X()-nStart;
348*cdf0e10cSrcweir 		rPnt.X()=nStart;
349*cdf0e10cSrcweir 		if (bC1) {
350*cdf0e10cSrcweir 			dxC1=pC1->X()-nStart;
351*cdf0e10cSrcweir 			pC1->X()=nStart;
352*cdf0e10cSrcweir 		}
353*cdf0e10cSrcweir 		if (bC2) {
354*cdf0e10cSrcweir 			dxC2=pC2->X()-nStart;
355*cdf0e10cSrcweir 			pC2->X()=nStart;
356*cdf0e10cSrcweir 		}
357*cdf0e10cSrcweir 	} else {
358*cdf0e10cSrcweir 		long nStart=rCenter.Y()-rRad.Y();
359*cdf0e10cSrcweir 		dy1=rPnt.Y()-nStart;
360*cdf0e10cSrcweir 		rPnt.Y()=nStart;
361*cdf0e10cSrcweir 		if (bC1) {
362*cdf0e10cSrcweir 			dyC1=pC1->Y()-nStart;
363*cdf0e10cSrcweir 			pC1->Y()=nStart;
364*cdf0e10cSrcweir 		}
365*cdf0e10cSrcweir 		if (bC2) {
366*cdf0e10cSrcweir 			dyC2=pC2->Y()-nStart;
367*cdf0e10cSrcweir 			pC2->Y()=nStart;
368*cdf0e10cSrcweir 		}
369*cdf0e10cSrcweir 	}
370*cdf0e10cSrcweir 	double nWink=GetCrookAngle(rPnt,rCenter,rRad,bVert);
371*cdf0e10cSrcweir 	double sn=sin(nWink);
372*cdf0e10cSrcweir 	double cs=cos(nWink);
373*cdf0e10cSrcweir 	RotatePoint(rPnt,rCenter,sn,cs);
374*cdf0e10cSrcweir 	if (bC1) { if (bVert) pC1->Y()-=y0-rCenter.Y(); else pC1->X()-=x0-rCenter.X(); RotatePoint(*pC1,rCenter,sn,cs); }
375*cdf0e10cSrcweir 	if (bC2) { if (bVert) pC2->Y()-=y0-rCenter.Y(); else pC2->X()-=x0-rCenter.X(); RotatePoint(*pC2,rCenter,sn,cs); }
376*cdf0e10cSrcweir 	if (bVert) {
377*cdf0e10cSrcweir 		rPnt.X()+=dx1;
378*cdf0e10cSrcweir 		if (bC1) pC1->X()+=dxC1;
379*cdf0e10cSrcweir 		if (bC2) pC2->X()+=dxC2;
380*cdf0e10cSrcweir 	} else {
381*cdf0e10cSrcweir 		rPnt.Y()+=dy1;
382*cdf0e10cSrcweir 		if (bC1) pC1->Y()+=dyC1;
383*cdf0e10cSrcweir 		if (bC2) pC2->Y()+=dyC2;
384*cdf0e10cSrcweir 	}
385*cdf0e10cSrcweir 	rSin=sn;
386*cdf0e10cSrcweir 	rCos=cs;
387*cdf0e10cSrcweir 	return nWink;
388*cdf0e10cSrcweir }
389*cdf0e10cSrcweir 
390*cdf0e10cSrcweir double CrookStretchXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
391*cdf0e10cSrcweir 						  const Point& rRad, double& rSin, double& rCos, FASTBOOL bVert,
392*cdf0e10cSrcweir 						  const Rectangle rRefRect)
393*cdf0e10cSrcweir {
394*cdf0e10cSrcweir 	//FASTBOOL bC1=pC1!=NULL;
395*cdf0e10cSrcweir 	//FASTBOOL bC2=pC2!=NULL;
396*cdf0e10cSrcweir 	//long x0=rPnt.X();
397*cdf0e10cSrcweir 	long y0=rPnt.Y();
398*cdf0e10cSrcweir 	CrookSlantXPoint(rPnt,pC1,pC2,rCenter,rRad,rSin,rCos,bVert);
399*cdf0e10cSrcweir 	if (bVert) {
400*cdf0e10cSrcweir 	} else {
401*cdf0e10cSrcweir 		//long nBase=rCenter.Y()-rRad.Y();
402*cdf0e10cSrcweir 		long nTop=rRefRect.Top();
403*cdf0e10cSrcweir 		long nBtm=rRefRect.Bottom();
404*cdf0e10cSrcweir 		long nHgt=nBtm-nTop;
405*cdf0e10cSrcweir 		long dy=rPnt.Y()-y0;
406*cdf0e10cSrcweir 		//FASTBOOL bOben=rRad.Y()<0;
407*cdf0e10cSrcweir 		double a=((double)(y0-nTop))/nHgt;
408*cdf0e10cSrcweir 		a*=dy;
409*cdf0e10cSrcweir 		rPnt.Y()=y0+Round(a);
410*cdf0e10cSrcweir 	} return 0.0;
411*cdf0e10cSrcweir }
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir void CrookRotatePoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
416*cdf0e10cSrcweir {
417*cdf0e10cSrcweir 	double nSin,nCos;
418*cdf0e10cSrcweir 	sal_uInt16 nPointAnz=rPoly.GetPointCount();
419*cdf0e10cSrcweir 	sal_uInt16 i=0;
420*cdf0e10cSrcweir 	while (i<nPointAnz) {
421*cdf0e10cSrcweir 		Point* pPnt=&rPoly[i];
422*cdf0e10cSrcweir 		Point* pC1=NULL;
423*cdf0e10cSrcweir 		Point* pC2=NULL;
424*cdf0e10cSrcweir 		if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
425*cdf0e10cSrcweir 			pC1=pPnt;
426*cdf0e10cSrcweir 			i++;
427*cdf0e10cSrcweir 			pPnt=&rPoly[i];
428*cdf0e10cSrcweir 		}
429*cdf0e10cSrcweir 		i++;
430*cdf0e10cSrcweir 		if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
431*cdf0e10cSrcweir 			pC2=&rPoly[i];
432*cdf0e10cSrcweir 			i++;
433*cdf0e10cSrcweir 		}
434*cdf0e10cSrcweir 		CrookRotateXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
435*cdf0e10cSrcweir 	}
436*cdf0e10cSrcweir }
437*cdf0e10cSrcweir 
438*cdf0e10cSrcweir void CrookSlantPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
439*cdf0e10cSrcweir {
440*cdf0e10cSrcweir 	double nSin,nCos;
441*cdf0e10cSrcweir 	sal_uInt16 nPointAnz=rPoly.GetPointCount();
442*cdf0e10cSrcweir 	sal_uInt16 i=0;
443*cdf0e10cSrcweir 	while (i<nPointAnz) {
444*cdf0e10cSrcweir 		Point* pPnt=&rPoly[i];
445*cdf0e10cSrcweir 		Point* pC1=NULL;
446*cdf0e10cSrcweir 		Point* pC2=NULL;
447*cdf0e10cSrcweir 		if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
448*cdf0e10cSrcweir 			pC1=pPnt;
449*cdf0e10cSrcweir 			i++;
450*cdf0e10cSrcweir 			pPnt=&rPoly[i];
451*cdf0e10cSrcweir 		}
452*cdf0e10cSrcweir 		i++;
453*cdf0e10cSrcweir 		if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
454*cdf0e10cSrcweir 			pC2=&rPoly[i];
455*cdf0e10cSrcweir 			i++;
456*cdf0e10cSrcweir 		}
457*cdf0e10cSrcweir 		CrookSlantXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert);
458*cdf0e10cSrcweir 	}
459*cdf0e10cSrcweir }
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir void CrookStretchPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert, const Rectangle rRefRect)
462*cdf0e10cSrcweir {
463*cdf0e10cSrcweir 	double nSin,nCos;
464*cdf0e10cSrcweir 	sal_uInt16 nPointAnz=rPoly.GetPointCount();
465*cdf0e10cSrcweir 	sal_uInt16 i=0;
466*cdf0e10cSrcweir 	while (i<nPointAnz) {
467*cdf0e10cSrcweir 		Point* pPnt=&rPoly[i];
468*cdf0e10cSrcweir 		Point* pC1=NULL;
469*cdf0e10cSrcweir 		Point* pC2=NULL;
470*cdf0e10cSrcweir 		if (i+1<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt links
471*cdf0e10cSrcweir 			pC1=pPnt;
472*cdf0e10cSrcweir 			i++;
473*cdf0e10cSrcweir 			pPnt=&rPoly[i];
474*cdf0e10cSrcweir 		}
475*cdf0e10cSrcweir 		i++;
476*cdf0e10cSrcweir 		if (i<nPointAnz && rPoly.IsControl(i)) { // Kontrollpunkt rechts
477*cdf0e10cSrcweir 			pC2=&rPoly[i];
478*cdf0e10cSrcweir 			i++;
479*cdf0e10cSrcweir 		}
480*cdf0e10cSrcweir 		CrookStretchXPoint(*pPnt,pC1,pC2,rCenter,rRad,nSin,nCos,bVert,rRefRect);
481*cdf0e10cSrcweir 	}
482*cdf0e10cSrcweir }
483*cdf0e10cSrcweir 
484*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir void CrookRotatePoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
487*cdf0e10cSrcweir {
488*cdf0e10cSrcweir 	sal_uInt16 nPolyAnz=rPoly.Count();
489*cdf0e10cSrcweir 	for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
490*cdf0e10cSrcweir 		CrookRotatePoly(rPoly[nPolyNum],rCenter,rRad,bVert);
491*cdf0e10cSrcweir 	}
492*cdf0e10cSrcweir }
493*cdf0e10cSrcweir 
494*cdf0e10cSrcweir void CrookSlantPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert)
495*cdf0e10cSrcweir {
496*cdf0e10cSrcweir 	sal_uInt16 nPolyAnz=rPoly.Count();
497*cdf0e10cSrcweir 	for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
498*cdf0e10cSrcweir 		CrookSlantPoly(rPoly[nPolyNum],rCenter,rRad,bVert);
499*cdf0e10cSrcweir 	}
500*cdf0e10cSrcweir }
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir void CrookStretchPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, FASTBOOL bVert, const Rectangle rRefRect)
503*cdf0e10cSrcweir {
504*cdf0e10cSrcweir 	sal_uInt16 nPolyAnz=rPoly.Count();
505*cdf0e10cSrcweir 	for (sal_uInt16 nPolyNum=0; nPolyNum<nPolyAnz; nPolyNum++) {
506*cdf0e10cSrcweir 		CrookStretchPoly(rPoly[nPolyNum],rCenter,rRad,bVert,rRefRect);
507*cdf0e10cSrcweir 	}
508*cdf0e10cSrcweir }
509*cdf0e10cSrcweir 
510*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir long GetAngle(const Point& rPnt)
513*cdf0e10cSrcweir {
514*cdf0e10cSrcweir 	long a=0;
515*cdf0e10cSrcweir 	if (rPnt.Y()==0) {
516*cdf0e10cSrcweir 		if (rPnt.X()<0) a=-18000;
517*cdf0e10cSrcweir 	} else if (rPnt.X()==0) {
518*cdf0e10cSrcweir 		if (rPnt.Y()>0) a=-9000;
519*cdf0e10cSrcweir 		else a=9000;
520*cdf0e10cSrcweir 	} else {
521*cdf0e10cSrcweir 		a=Round((atan2((double)-rPnt.Y(),(double)rPnt.X())/nPi180));
522*cdf0e10cSrcweir 	}
523*cdf0e10cSrcweir 	return a;
524*cdf0e10cSrcweir }
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir long NormAngle180(long a)
527*cdf0e10cSrcweir {
528*cdf0e10cSrcweir 	while (a<18000) a+=36000;
529*cdf0e10cSrcweir 	while (a>=18000) a-=36000;
530*cdf0e10cSrcweir 	return a;
531*cdf0e10cSrcweir }
532*cdf0e10cSrcweir 
533*cdf0e10cSrcweir long NormAngle360(long a)
534*cdf0e10cSrcweir {
535*cdf0e10cSrcweir 	while (a<0) a+=36000;
536*cdf0e10cSrcweir 	while (a>=36000) a-=36000;
537*cdf0e10cSrcweir 	return a;
538*cdf0e10cSrcweir }
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir sal_uInt16 GetAngleSector(long nWink)
541*cdf0e10cSrcweir {
542*cdf0e10cSrcweir 	while (nWink<0) nWink+=36000;
543*cdf0e10cSrcweir 	while (nWink>=36000) nWink-=36000;
544*cdf0e10cSrcweir 	if (nWink< 9000) return 0;
545*cdf0e10cSrcweir 	if (nWink<18000) return 1;
546*cdf0e10cSrcweir 	if (nWink<27000) return 2;
547*cdf0e10cSrcweir 	return 3;
548*cdf0e10cSrcweir }
549*cdf0e10cSrcweir 
550*cdf0e10cSrcweir long GetLen(const Point& rPnt)
551*cdf0e10cSrcweir {
552*cdf0e10cSrcweir 	long x=Abs(rPnt.X());
553*cdf0e10cSrcweir 	long y=Abs(rPnt.Y());
554*cdf0e10cSrcweir 	if (x+y<0x8000) { // weil 7FFF * 7FFF * 2 = 7FFE0002
555*cdf0e10cSrcweir 		x*=x;
556*cdf0e10cSrcweir 		y*=y;
557*cdf0e10cSrcweir 		x+=y;
558*cdf0e10cSrcweir 		x=Round(sqrt((double)x));
559*cdf0e10cSrcweir 		return x;
560*cdf0e10cSrcweir 	} else {
561*cdf0e10cSrcweir 		double nx=x;
562*cdf0e10cSrcweir 		double ny=y;
563*cdf0e10cSrcweir 		nx*=nx;
564*cdf0e10cSrcweir 		ny*=ny;
565*cdf0e10cSrcweir 		nx+=ny;
566*cdf0e10cSrcweir 		nx=sqrt(nx);
567*cdf0e10cSrcweir 		if (nx>0x7FFFFFFF) {
568*cdf0e10cSrcweir 			return 0x7FFFFFFF; // Ueberlauf, mehr is nich!
569*cdf0e10cSrcweir 		} else {
570*cdf0e10cSrcweir 			return Round(nx);
571*cdf0e10cSrcweir 		}
572*cdf0e10cSrcweir 	}
573*cdf0e10cSrcweir }
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
576*cdf0e10cSrcweir 
577*cdf0e10cSrcweir void GeoStat::RecalcSinCos()
578*cdf0e10cSrcweir {
579*cdf0e10cSrcweir 	if (nDrehWink==0) {
580*cdf0e10cSrcweir 		nSin=0.0;
581*cdf0e10cSrcweir 		nCos=1.0;
582*cdf0e10cSrcweir 	} else {
583*cdf0e10cSrcweir 		double a=nDrehWink*nPi180;
584*cdf0e10cSrcweir 		nSin=sin(a);
585*cdf0e10cSrcweir 		nCos=cos(a);
586*cdf0e10cSrcweir 	}
587*cdf0e10cSrcweir }
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir void GeoStat::RecalcTan()
590*cdf0e10cSrcweir {
591*cdf0e10cSrcweir 	if (nShearWink==0) {
592*cdf0e10cSrcweir 		nTan=0.0;
593*cdf0e10cSrcweir 	} else {
594*cdf0e10cSrcweir 		double a=nShearWink*nPi180;
595*cdf0e10cSrcweir 		nTan=tan(a);
596*cdf0e10cSrcweir 	}
597*cdf0e10cSrcweir }
598*cdf0e10cSrcweir 
599*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir Polygon Rect2Poly(const Rectangle& rRect, const GeoStat& rGeo)
602*cdf0e10cSrcweir {
603*cdf0e10cSrcweir 	Polygon aPol(5);
604*cdf0e10cSrcweir 	aPol[0]=rRect.TopLeft();
605*cdf0e10cSrcweir 	aPol[1]=rRect.TopRight();
606*cdf0e10cSrcweir 	aPol[2]=rRect.BottomRight();
607*cdf0e10cSrcweir 	aPol[3]=rRect.BottomLeft();
608*cdf0e10cSrcweir 	aPol[4]=rRect.TopLeft();
609*cdf0e10cSrcweir 	if (rGeo.nShearWink!=0) ShearPoly(aPol,rRect.TopLeft(),rGeo.nTan);
610*cdf0e10cSrcweir 	if (rGeo.nDrehWink!=0) RotatePoly(aPol,rRect.TopLeft(),rGeo.nSin,rGeo.nCos);
611*cdf0e10cSrcweir 	return aPol;
612*cdf0e10cSrcweir }
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir void Poly2Rect(const Polygon& rPol, Rectangle& rRect, GeoStat& rGeo)
615*cdf0e10cSrcweir {
616*cdf0e10cSrcweir 	rGeo.nDrehWink=GetAngle(rPol[1]-rPol[0]);
617*cdf0e10cSrcweir 	rGeo.nDrehWink=NormAngle360(rGeo.nDrehWink);
618*cdf0e10cSrcweir 	// Drehung ist damit im Kasten
619*cdf0e10cSrcweir 	rGeo.RecalcSinCos();
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir 	Point aPt1(rPol[1]-rPol[0]);
622*cdf0e10cSrcweir 	if (rGeo.nDrehWink!=0) RotatePoint(aPt1,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin fuer Rueckdrehung
623*cdf0e10cSrcweir 	long nWdt=aPt1.X();
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir 	Point aPt0(rPol[0]);
626*cdf0e10cSrcweir 	Point aPt3(rPol[3]-rPol[0]);
627*cdf0e10cSrcweir 	if (rGeo.nDrehWink!=0) RotatePoint(aPt3,Point(0,0),-rGeo.nSin,rGeo.nCos); // -Sin fuer Rueckdrehung
628*cdf0e10cSrcweir 	long nHgt=aPt3.Y();
629*cdf0e10cSrcweir 
630*cdf0e10cSrcweir 	if(aPt3.X())
631*cdf0e10cSrcweir 	{
632*cdf0e10cSrcweir 		// #i74358# the axes are not orthogonal, so for getting the correct height,
633*cdf0e10cSrcweir 		// calculate the length of aPt3
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir 		// #i74358# this change was wrong, in the field of the old geometry stuff
636*cdf0e10cSrcweir 		// it is not an error. The new height always is the same as before; shear
637*cdf0e10cSrcweir 		// does not change object height at all. This is different from the interactions,
638*cdf0e10cSrcweir 		// but obviously wanted in the old versions.
639*cdf0e10cSrcweir 		//
640*cdf0e10cSrcweir 		// nHgt = static_cast< long >(sqrt(static_cast< double >(aPt3.X() * aPt3.X() + aPt3.Y() * aPt3.Y())));
641*cdf0e10cSrcweir 	}
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir     long nShW=GetAngle(aPt3);
644*cdf0e10cSrcweir 	nShW-=27000; // ShearWink wird zur Senkrechten gemessen
645*cdf0e10cSrcweir 	nShW=-nShW;  // Negieren, denn '+' ist Rechtskursivierung
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir 	FASTBOOL bMirr=aPt3.Y()<0;
648*cdf0e10cSrcweir 	if (bMirr) { // "Punktetausch" bei Spiegelung
649*cdf0e10cSrcweir 		nHgt=-nHgt;
650*cdf0e10cSrcweir 		nShW+=18000;
651*cdf0e10cSrcweir 		aPt0=rPol[3];
652*cdf0e10cSrcweir 	}
653*cdf0e10cSrcweir 	nShW=NormAngle180(nShW);
654*cdf0e10cSrcweir 	if (nShW<-9000 || nShW>9000) {
655*cdf0e10cSrcweir 		nShW=NormAngle180(nShW+18000);
656*cdf0e10cSrcweir 	}
657*cdf0e10cSrcweir 	if (nShW<-SDRMAXSHEAR) nShW=-SDRMAXSHEAR; // ShearWinkel begrenzen auf +/- 89.00 deg
658*cdf0e10cSrcweir 	if (nShW>SDRMAXSHEAR)  nShW=SDRMAXSHEAR;
659*cdf0e10cSrcweir 	rGeo.nShearWink=nShW;
660*cdf0e10cSrcweir 	rGeo.RecalcTan();
661*cdf0e10cSrcweir 	Point aRU(aPt0);
662*cdf0e10cSrcweir 	aRU.X()+=nWdt;
663*cdf0e10cSrcweir 	aRU.Y()+=nHgt;
664*cdf0e10cSrcweir 	rRect=Rectangle(aPt0,aRU);
665*cdf0e10cSrcweir }
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
668*cdf0e10cSrcweir 
669*cdf0e10cSrcweir void OrthoDistance8(const Point& rPt0, Point& rPt, FASTBOOL bBigOrtho)
670*cdf0e10cSrcweir {
671*cdf0e10cSrcweir 	long dx=rPt.X()-rPt0.X();
672*cdf0e10cSrcweir 	long dy=rPt.Y()-rPt0.Y();
673*cdf0e10cSrcweir 	long dxa=Abs(dx);
674*cdf0e10cSrcweir 	long dya=Abs(dy);
675*cdf0e10cSrcweir 	if (dx==0 || dy==0 || dxa==dya) return;
676*cdf0e10cSrcweir 	if (dxa>=dya*2) { rPt.Y()=rPt0.Y(); return; }
677*cdf0e10cSrcweir 	if (dya>=dxa*2) { rPt.X()=rPt0.X(); return; }
678*cdf0e10cSrcweir 	if ((dxa<dya) != bBigOrtho) {
679*cdf0e10cSrcweir 		rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
680*cdf0e10cSrcweir 	} else {
681*cdf0e10cSrcweir 		rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
682*cdf0e10cSrcweir 	}
683*cdf0e10cSrcweir }
684*cdf0e10cSrcweir 
685*cdf0e10cSrcweir void OrthoDistance4(const Point& rPt0, Point& rPt, FASTBOOL bBigOrtho)
686*cdf0e10cSrcweir {
687*cdf0e10cSrcweir 	long dx=rPt.X()-rPt0.X();
688*cdf0e10cSrcweir 	long dy=rPt.Y()-rPt0.Y();
689*cdf0e10cSrcweir 	long dxa=Abs(dx);
690*cdf0e10cSrcweir 	long dya=Abs(dy);
691*cdf0e10cSrcweir 	if ((dxa<dya) != bBigOrtho) {
692*cdf0e10cSrcweir 		rPt.Y()=rPt0.Y()+(dxa* (dy>=0 ? 1 : -1) );
693*cdf0e10cSrcweir 	} else {
694*cdf0e10cSrcweir 		rPt.X()=rPt0.X()+(dya* (dx>=0 ? 1 : -1) );
695*cdf0e10cSrcweir 	}
696*cdf0e10cSrcweir }
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
699*cdf0e10cSrcweir 
700*cdf0e10cSrcweir long BigMulDiv(long nVal, long nMul, long nDiv)
701*cdf0e10cSrcweir {
702*cdf0e10cSrcweir 	BigInt aVal(nVal);
703*cdf0e10cSrcweir 	aVal*=nMul;
704*cdf0e10cSrcweir 	if (aVal.IsNeg()!=(nDiv<0)) {
705*cdf0e10cSrcweir 		aVal-=nDiv/2; // fuer korrektes Runden
706*cdf0e10cSrcweir 	} else {
707*cdf0e10cSrcweir 		aVal+=nDiv/2; // fuer korrektes Runden
708*cdf0e10cSrcweir 	}
709*cdf0e10cSrcweir 	if(nDiv)
710*cdf0e10cSrcweir 	{
711*cdf0e10cSrcweir 		aVal/=nDiv;
712*cdf0e10cSrcweir 		return long(aVal);
713*cdf0e10cSrcweir 	}
714*cdf0e10cSrcweir 	return 0x7fffffff;
715*cdf0e10cSrcweir }
716*cdf0e10cSrcweir 
717*cdf0e10cSrcweir void Kuerzen(Fraction& rF, unsigned nDigits)
718*cdf0e10cSrcweir {
719*cdf0e10cSrcweir 	sal_Int32 nMul=rF.GetNumerator();
720*cdf0e10cSrcweir 	sal_Int32 nDiv=rF.GetDenominator();
721*cdf0e10cSrcweir 	FASTBOOL bNeg=sal_False;
722*cdf0e10cSrcweir 	if (nMul<0) { nMul=-nMul; bNeg=!bNeg; }
723*cdf0e10cSrcweir 	if (nDiv<0) { nDiv=-nDiv; bNeg=!bNeg; }
724*cdf0e10cSrcweir 	if (nMul==0 || nDiv==0) return;
725*cdf0e10cSrcweir 	sal_uInt32 a;
726*cdf0e10cSrcweir 	a=sal_uInt32(nMul); unsigned nMulZ=0; // Fuehrende Nullen zaehlen
727*cdf0e10cSrcweir 	while (a<0x00800000) { nMulZ+=8; a<<=8; }
728*cdf0e10cSrcweir 	while (a<0x80000000) { nMulZ++; a<<=1; }
729*cdf0e10cSrcweir 	a=sal_uInt32(nDiv); unsigned nDivZ=0; // Fuehrende Nullen zaehlen
730*cdf0e10cSrcweir 	while (a<0x00800000) { nDivZ+=8; a<<=8; }
731*cdf0e10cSrcweir 	while (a<0x80000000) { nDivZ++; a<<=1; }
732*cdf0e10cSrcweir 	// Anzahl der verwendeten Digits bestimmen
733*cdf0e10cSrcweir 	int nMulDigits=32-nMulZ;
734*cdf0e10cSrcweir 	int nDivDigits=32-nDivZ;
735*cdf0e10cSrcweir 	// Nun bestimmen, wieviele Stellen hinten weg koennen
736*cdf0e10cSrcweir 	int nMulWeg=nMulDigits-nDigits; if (nMulWeg<0) nMulWeg=0;
737*cdf0e10cSrcweir 	int nDivWeg=nDivDigits-nDigits; if (nDivWeg<0) nDivWeg=0;
738*cdf0e10cSrcweir 	int nWeg=Min(nMulWeg,nDivWeg);
739*cdf0e10cSrcweir 	nMul>>=nWeg;
740*cdf0e10cSrcweir 	nDiv>>=nWeg;
741*cdf0e10cSrcweir 	if (nMul==0 || nDiv==0) {
742*cdf0e10cSrcweir 		DBG_WARNING("Oups, beim kuerzen einer Fraction hat sich Joe verrechnet.");
743*cdf0e10cSrcweir 		return;
744*cdf0e10cSrcweir 	}
745*cdf0e10cSrcweir 	if (bNeg) nMul=-nMul;
746*cdf0e10cSrcweir 	rF=Fraction(nMul,nDiv);
747*cdf0e10cSrcweir }
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
750*cdf0e10cSrcweir // Wieviele eU-Einheiten passen in einen mm bzw. Inch?
751*cdf0e10cSrcweir // Oder wie gross ist ein eU in mm bzw. Inch, und davon der Kehrwert
752*cdf0e10cSrcweir 
753*cdf0e10cSrcweir FrPair GetInchOrMM(MapUnit eU)
754*cdf0e10cSrcweir {
755*cdf0e10cSrcweir 	switch (eU) {
756*cdf0e10cSrcweir 		case MAP_1000TH_INCH: return FrPair(1000,1);
757*cdf0e10cSrcweir 		case MAP_100TH_INCH : return FrPair( 100,1);
758*cdf0e10cSrcweir 		case MAP_10TH_INCH  : return FrPair(  10,1);
759*cdf0e10cSrcweir 		case MAP_INCH       : return FrPair(   1,1);
760*cdf0e10cSrcweir 		case MAP_POINT      : return FrPair(  72,1);
761*cdf0e10cSrcweir 		case MAP_TWIP       : return FrPair(1440,1);
762*cdf0e10cSrcweir 		case MAP_100TH_MM   : return FrPair( 100,1);
763*cdf0e10cSrcweir 		case MAP_10TH_MM    : return FrPair(  10,1);
764*cdf0e10cSrcweir 		case MAP_MM         : return FrPair(   1,1);
765*cdf0e10cSrcweir 		case MAP_CM         : return FrPair(   1,10);
766*cdf0e10cSrcweir 		case MAP_PIXEL      : {
767*cdf0e10cSrcweir 			VirtualDevice aVD;
768*cdf0e10cSrcweir 			aVD.SetMapMode(MapMode(MAP_100TH_MM));
769*cdf0e10cSrcweir 			Point aP(aVD.PixelToLogic(Point(64,64))); // 64 Pixel fuer bessere Genauigkeit
770*cdf0e10cSrcweir 			return FrPair(6400,aP.X(),6400,aP.Y());
771*cdf0e10cSrcweir 		}
772*cdf0e10cSrcweir 		case MAP_APPFONT: case MAP_SYSFONT: {
773*cdf0e10cSrcweir 			VirtualDevice aVD;
774*cdf0e10cSrcweir 			aVD.SetMapMode(MapMode(eU));
775*cdf0e10cSrcweir 			Point aP(aVD.LogicToPixel(Point(32,32))); // 32 Einheiten fuer bessere Genauigkeit
776*cdf0e10cSrcweir 			aVD.SetMapMode(MapMode(MAP_100TH_MM));
777*cdf0e10cSrcweir 			aP=aVD.PixelToLogic(aP);
778*cdf0e10cSrcweir 			return FrPair(3200,aP.X(),3200,aP.Y());
779*cdf0e10cSrcweir 		}
780*cdf0e10cSrcweir 		default: break;
781*cdf0e10cSrcweir 	}
782*cdf0e10cSrcweir 	return Fraction(1,1);
783*cdf0e10cSrcweir }
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir FrPair GetInchOrMM(FieldUnit eU)
786*cdf0e10cSrcweir {
787*cdf0e10cSrcweir 	switch (eU) {
788*cdf0e10cSrcweir 		case FUNIT_INCH       : return FrPair(   1,1);
789*cdf0e10cSrcweir 		case FUNIT_POINT      : return FrPair(  72,1);
790*cdf0e10cSrcweir 		case FUNIT_TWIP       : return FrPair(1440,1);
791*cdf0e10cSrcweir 		case FUNIT_100TH_MM   : return FrPair( 100,1);
792*cdf0e10cSrcweir 		case FUNIT_MM         : return FrPair(   1,1);
793*cdf0e10cSrcweir 		case FUNIT_CM         : return FrPair(   1,10);
794*cdf0e10cSrcweir 		case FUNIT_M          : return FrPair(   1,1000);
795*cdf0e10cSrcweir 		case FUNIT_KM         : return FrPair(   1,1000000);
796*cdf0e10cSrcweir 		case FUNIT_PICA       : return FrPair(   6,1);
797*cdf0e10cSrcweir 		case FUNIT_FOOT       : return FrPair(   1,12);
798*cdf0e10cSrcweir 		case FUNIT_MILE       : return FrPair(   1,63360);
799*cdf0e10cSrcweir 		default: break;
800*cdf0e10cSrcweir 	}
801*cdf0e10cSrcweir 	return Fraction(1,1);
802*cdf0e10cSrcweir }
803*cdf0e10cSrcweir 
804*cdf0e10cSrcweir // Den Faktor berechnen, der anzuwenden ist um n Einheiten von eS nach
805*cdf0e10cSrcweir // eD umzurechnen. Z.B. GetMapFactor(UNIT_MM,UNIT_100TH_MM) => 100.
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir FrPair GetMapFactor(MapUnit eS, MapUnit eD)
808*cdf0e10cSrcweir {
809*cdf0e10cSrcweir 	if (eS==eD) return FrPair(1,1,1,1);
810*cdf0e10cSrcweir 	FrPair aS(GetInchOrMM(eS));
811*cdf0e10cSrcweir 	FrPair aD(GetInchOrMM(eD));
812*cdf0e10cSrcweir 	FASTBOOL bSInch=IsInch(eS);
813*cdf0e10cSrcweir 	FASTBOOL bDInch=IsInch(eD);
814*cdf0e10cSrcweir 	FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
815*cdf0e10cSrcweir 	if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
816*cdf0e10cSrcweir 	if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
817*cdf0e10cSrcweir 	return aRet;
818*cdf0e10cSrcweir };
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir FrPair GetMapFactor(MapUnit eS, FieldUnit eD)
821*cdf0e10cSrcweir {
822*cdf0e10cSrcweir 	FrPair aS(GetInchOrMM(eS));
823*cdf0e10cSrcweir 	FrPair aD(GetInchOrMM(eD));
824*cdf0e10cSrcweir 	FASTBOOL bSInch=IsInch(eS);
825*cdf0e10cSrcweir 	FASTBOOL bDInch=IsInch(eD);
826*cdf0e10cSrcweir 	FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
827*cdf0e10cSrcweir 	if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
828*cdf0e10cSrcweir 	if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
829*cdf0e10cSrcweir 	return aRet;
830*cdf0e10cSrcweir };
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir FrPair GetMapFactor(FieldUnit eS, MapUnit eD)
833*cdf0e10cSrcweir {
834*cdf0e10cSrcweir 	FrPair aS(GetInchOrMM(eS));
835*cdf0e10cSrcweir 	FrPair aD(GetInchOrMM(eD));
836*cdf0e10cSrcweir 	FASTBOOL bSInch=IsInch(eS);
837*cdf0e10cSrcweir 	FASTBOOL bDInch=IsInch(eD);
838*cdf0e10cSrcweir 	FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
839*cdf0e10cSrcweir 	if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
840*cdf0e10cSrcweir 	if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
841*cdf0e10cSrcweir 	return aRet;
842*cdf0e10cSrcweir };
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir FrPair GetMapFactor(FieldUnit eS, FieldUnit eD)
845*cdf0e10cSrcweir {
846*cdf0e10cSrcweir 	if (eS==eD) return FrPair(1,1,1,1);
847*cdf0e10cSrcweir 	FrPair aS(GetInchOrMM(eS));
848*cdf0e10cSrcweir 	FrPair aD(GetInchOrMM(eD));
849*cdf0e10cSrcweir 	FASTBOOL bSInch=IsInch(eS);
850*cdf0e10cSrcweir 	FASTBOOL bDInch=IsInch(eD);
851*cdf0e10cSrcweir 	FrPair aRet(aD.X()/aS.X(),aD.Y()/aS.Y());
852*cdf0e10cSrcweir 	if (bSInch && !bDInch) { aRet.X()*=Fraction(127,5); aRet.Y()*=Fraction(127,5); }
853*cdf0e10cSrcweir 	if (!bSInch && bDInch) { aRet.X()*=Fraction(5,127); aRet.Y()*=Fraction(5,127); }
854*cdf0e10cSrcweir 	return aRet;
855*cdf0e10cSrcweir };
856*cdf0e10cSrcweir 
857*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir 	// 1 mile    =  8 furlong = 63.360" = 1.609.344,0mm
860*cdf0e10cSrcweir 	// 1 furlong = 10 chains  =  7.920" =   201.168,0mm
861*cdf0e10cSrcweir 	// 1 chain   =  4 poles   =    792" =    20.116,8mm
862*cdf0e10cSrcweir 	// 1 pole    =  5 1/2 yd  =    198" =     5.029,2mm
863*cdf0e10cSrcweir 	// 1 yd      =  3 ft      =     36" =       914,4mm
864*cdf0e10cSrcweir 	// 1 ft      = 12 "       =      1" =       304,8mm
865*cdf0e10cSrcweir 
866*cdf0e10cSrcweir void GetMeterOrInch(MapUnit eMU, short& rnKomma, long& rnMul, long& rnDiv, int& rbMetr, int& rbInch)
867*cdf0e10cSrcweir {
868*cdf0e10cSrcweir 	rnMul=1; rnDiv=1;
869*cdf0e10cSrcweir 	short nKomma=0;
870*cdf0e10cSrcweir 	FASTBOOL bMetr=sal_False,bInch=sal_False;
871*cdf0e10cSrcweir 	switch (eMU) {
872*cdf0e10cSrcweir 		// Metrisch
873*cdf0e10cSrcweir 		case MAP_100TH_MM   : bMetr=sal_True; nKomma=5; break;
874*cdf0e10cSrcweir 		case MAP_10TH_MM    : bMetr=sal_True; nKomma=4; break;
875*cdf0e10cSrcweir 		case MAP_MM         : bMetr=sal_True; nKomma=3; break;
876*cdf0e10cSrcweir 		case MAP_CM         : bMetr=sal_True; nKomma=2; break;
877*cdf0e10cSrcweir 		// Inch
878*cdf0e10cSrcweir 		case MAP_1000TH_INCH: bInch=sal_True; nKomma=3; break;
879*cdf0e10cSrcweir 		case MAP_100TH_INCH : bInch=sal_True; nKomma=2; break;
880*cdf0e10cSrcweir 		case MAP_10TH_INCH  : bInch=sal_True; nKomma=1; break;
881*cdf0e10cSrcweir 		case MAP_INCH       : bInch=sal_True; nKomma=0; break;
882*cdf0e10cSrcweir 		case MAP_POINT      : bInch=sal_True; rnDiv=72;  break;          // 1Pt   = 1/72"
883*cdf0e10cSrcweir 		case MAP_TWIP       : bInch=sal_True; rnDiv=144; nKomma=1; break; // 1Twip = 1/1440"
884*cdf0e10cSrcweir 		// Sonstiges
885*cdf0e10cSrcweir 		case MAP_PIXEL      : break;
886*cdf0e10cSrcweir 		case MAP_SYSFONT    : break;
887*cdf0e10cSrcweir 		case MAP_APPFONT    : break;
888*cdf0e10cSrcweir 		case MAP_RELATIVE   : break;
889*cdf0e10cSrcweir 		default: break;
890*cdf0e10cSrcweir 	} // switch
891*cdf0e10cSrcweir 	rnKomma=nKomma;
892*cdf0e10cSrcweir 	rbMetr=bMetr;
893*cdf0e10cSrcweir 	rbInch=bInch;
894*cdf0e10cSrcweir }
895*cdf0e10cSrcweir 
896*cdf0e10cSrcweir void GetMeterOrInch(FieldUnit eFU, short& rnKomma, long& rnMul, long& rnDiv, int& rbMetr, int& rbInch)
897*cdf0e10cSrcweir {
898*cdf0e10cSrcweir 	rnMul=1; rnDiv=1;
899*cdf0e10cSrcweir 	short nKomma=0;
900*cdf0e10cSrcweir 	FASTBOOL bMetr=sal_False,bInch=sal_False;
901*cdf0e10cSrcweir 	switch (eFU) {
902*cdf0e10cSrcweir 		case FUNIT_NONE     : break;
903*cdf0e10cSrcweir 		// Metrisch
904*cdf0e10cSrcweir 		case FUNIT_100TH_MM : bMetr=sal_True; nKomma=5; break;
905*cdf0e10cSrcweir 		case FUNIT_MM       : bMetr=sal_True; nKomma=3; break;
906*cdf0e10cSrcweir 		case FUNIT_CM       : bMetr=sal_True; nKomma=2; break;
907*cdf0e10cSrcweir 		case FUNIT_M        : bMetr=sal_True; nKomma=0; break;
908*cdf0e10cSrcweir 		case FUNIT_KM       : bMetr=sal_True; nKomma=-3; break;
909*cdf0e10cSrcweir 		// Inch
910*cdf0e10cSrcweir 		case FUNIT_TWIP     : bInch=sal_True; rnDiv=144; nKomma=1; break;  // 1Twip = 1/1440"
911*cdf0e10cSrcweir 		case FUNIT_POINT    : bInch=sal_True; rnDiv=72; break;   // 1Pt   = 1/72"
912*cdf0e10cSrcweir 		case FUNIT_PICA     : bInch=sal_True; rnDiv=6; break;    // 1Pica = 1/6"  ?
913*cdf0e10cSrcweir 		case FUNIT_INCH     : bInch=sal_True; break;             // 1"    = 1"
914*cdf0e10cSrcweir 		case FUNIT_FOOT     : bInch=sal_True; rnMul=12; break;   // 1Ft   = 12"
915*cdf0e10cSrcweir 		case FUNIT_MILE     : bInch=sal_True; rnMul=6336; nKomma=-1; break; // 1mile = 63360"
916*cdf0e10cSrcweir 		// sonstiges
917*cdf0e10cSrcweir 		case FUNIT_CUSTOM   : break;
918*cdf0e10cSrcweir 		case FUNIT_PERCENT  : nKomma=2; break;
919*cdf0e10cSrcweir 	} // switch
920*cdf0e10cSrcweir 	rnKomma=nKomma;
921*cdf0e10cSrcweir 	rbMetr=bMetr;
922*cdf0e10cSrcweir 	rbInch=bInch;
923*cdf0e10cSrcweir }
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir void SdrFormatter::Undirty()
926*cdf0e10cSrcweir {
927*cdf0e10cSrcweir 	if (aScale.GetNumerator()==0 || aScale.GetDenominator()==0) aScale=Fraction(1,1);
928*cdf0e10cSrcweir 	FASTBOOL bSrcMetr,bSrcInch,bDstMetr,bDstInch;
929*cdf0e10cSrcweir 	long nMul1,nDiv1,nMul2,nDiv2;
930*cdf0e10cSrcweir 	short nKomma1,nKomma2;
931*cdf0e10cSrcweir 	// Zunaechst normalisieren auf m bzw. "
932*cdf0e10cSrcweir 	if (!bSrcFU) {
933*cdf0e10cSrcweir 		GetMeterOrInch(eSrcMU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
934*cdf0e10cSrcweir 	} else {
935*cdf0e10cSrcweir 		GetMeterOrInch(eSrcFU,nKomma1,nMul1,nDiv1,bSrcMetr,bSrcInch);
936*cdf0e10cSrcweir 	}
937*cdf0e10cSrcweir 	if (!bDstFU) {
938*cdf0e10cSrcweir 		GetMeterOrInch(eDstMU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
939*cdf0e10cSrcweir 	} else {
940*cdf0e10cSrcweir 		GetMeterOrInch(eDstFU,nKomma2,nMul2,nDiv2,bDstMetr,bDstInch);
941*cdf0e10cSrcweir 	}
942*cdf0e10cSrcweir 	nMul1*=nDiv2;
943*cdf0e10cSrcweir 	nDiv1*=nMul2;
944*cdf0e10cSrcweir 	nKomma1=nKomma1-nKomma2;
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir 	if (bSrcInch && bDstMetr) {
947*cdf0e10cSrcweir 		nKomma1+=4;
948*cdf0e10cSrcweir 		nMul1*=254;
949*cdf0e10cSrcweir 	}
950*cdf0e10cSrcweir 	if (bSrcMetr && bDstInch) {
951*cdf0e10cSrcweir 		nKomma1-=4;
952*cdf0e10cSrcweir 		nDiv1*=254;
953*cdf0e10cSrcweir 	}
954*cdf0e10cSrcweir 
955*cdf0e10cSrcweir 	// Temporaere Fraction zum Kuerzen
956*cdf0e10cSrcweir 	Fraction aTempFract(nMul1,nDiv1);
957*cdf0e10cSrcweir 	nMul1=aTempFract.GetNumerator();
958*cdf0e10cSrcweir 	nDiv1=aTempFract.GetDenominator();
959*cdf0e10cSrcweir 
960*cdf0e10cSrcweir 	nMul_=nMul1;
961*cdf0e10cSrcweir 	nDiv_=nDiv1;
962*cdf0e10cSrcweir 	nKomma_=nKomma1;
963*cdf0e10cSrcweir 	bDirty=sal_False;
964*cdf0e10cSrcweir }
965*cdf0e10cSrcweir 
966*cdf0e10cSrcweir 
967*cdf0e10cSrcweir void SdrFormatter::TakeStr(long nVal, XubString& rStr) const
968*cdf0e10cSrcweir {
969*cdf0e10cSrcweir 	sal_Unicode aNullCode('0');
970*cdf0e10cSrcweir 
971*cdf0e10cSrcweir 	if(!nVal)
972*cdf0e10cSrcweir 	{
973*cdf0e10cSrcweir 		rStr = UniString();
974*cdf0e10cSrcweir 		rStr += aNullCode;
975*cdf0e10cSrcweir 		return;
976*cdf0e10cSrcweir 	}
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir 	// Hier fallen trotzdem evtl. Nachkommastellen weg, wg. MulDiv statt Real
979*cdf0e10cSrcweir 	sal_Bool bNeg(nVal < 0);
980*cdf0e10cSrcweir     SvtSysLocale aSysLoc;
981*cdf0e10cSrcweir     const LocaleDataWrapper& rLoc = aSysLoc.GetLocaleData();
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir 	ForceUndirty();
984*cdf0e10cSrcweir 
985*cdf0e10cSrcweir 	sal_Int16 nK(nKomma_);
986*cdf0e10cSrcweir 	XubString aStr;
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir 	if(bNeg)
989*cdf0e10cSrcweir 		nVal = -nVal;
990*cdf0e10cSrcweir 
991*cdf0e10cSrcweir 	while(nK <= -3)
992*cdf0e10cSrcweir 	{
993*cdf0e10cSrcweir 		nVal *= 1000;
994*cdf0e10cSrcweir 		nK += 3;
995*cdf0e10cSrcweir 	}
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir 	while(nK <= -1)
998*cdf0e10cSrcweir 	{
999*cdf0e10cSrcweir 		nVal *= 10;
1000*cdf0e10cSrcweir 		nK++;
1001*cdf0e10cSrcweir 	}
1002*cdf0e10cSrcweir 
1003*cdf0e10cSrcweir 	if(nMul_ != nDiv_)
1004*cdf0e10cSrcweir 		nVal = BigMulDiv(nVal, nMul_, nDiv_);
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir 	aStr = UniString::CreateFromInt32(nVal);
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir 	if(nK > 0 && aStr.Len() <= nK )
1009*cdf0e10cSrcweir 	{
1010*cdf0e10cSrcweir 		// Komma erforderlich
1011*cdf0e10cSrcweir 		sal_Int16 nAnz(nK - aStr.Len());
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir         if(nAnz >= 0 && rLoc.isNumLeadingZero())
1014*cdf0e10cSrcweir 			nAnz++;
1015*cdf0e10cSrcweir 
1016*cdf0e10cSrcweir 		for(xub_StrLen  i=0; i<nAnz; i++)
1017*cdf0e10cSrcweir 			aStr.Insert(aNullCode, 0);
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir 		// zuviele Nachkommastellen abhacken
1020*cdf0e10cSrcweir         xub_StrLen nNumDigits(rLoc.getNumDigits());
1021*cdf0e10cSrcweir 		xub_StrLen nWeg(nK - nNumDigits);
1022*cdf0e10cSrcweir 
1023*cdf0e10cSrcweir 		if(nWeg > 0)
1024*cdf0e10cSrcweir 		{
1025*cdf0e10cSrcweir 			// hier muesste eigentlich noch gerundet werden!
1026*cdf0e10cSrcweir 			aStr.Erase(aStr.Len() - nWeg);
1027*cdf0e10cSrcweir 			nK = nNumDigits;
1028*cdf0e10cSrcweir 		}
1029*cdf0e10cSrcweir 	}
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir 	// Vorkommastellen fuer spaeter merken
1032*cdf0e10cSrcweir 	xub_StrLen nVorKomma(aStr.Len() - nK);
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir 	if(nK > 0)
1035*cdf0e10cSrcweir 	{
1036*cdf0e10cSrcweir 		// KommaChar einfuegen
1037*cdf0e10cSrcweir 		// erstmal trailing Zeros abhacken
1038*cdf0e10cSrcweir 		while(nK > 0 && aStr.GetChar(aStr.Len() - 1) == aNullCode)
1039*cdf0e10cSrcweir 		{
1040*cdf0e10cSrcweir 			aStr.Erase(aStr.Len() - 1);
1041*cdf0e10cSrcweir 			nK--;
1042*cdf0e10cSrcweir 		}
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir 		if(nK > 0)
1045*cdf0e10cSrcweir 		{
1046*cdf0e10cSrcweir 			// na, noch Nachkommastellen da?
1047*cdf0e10cSrcweir             sal_Unicode cDec(rLoc.getNumDecimalSep().GetChar(0));
1048*cdf0e10cSrcweir 			aStr.Insert(cDec, nVorKomma);
1049*cdf0e10cSrcweir 		}
1050*cdf0e10cSrcweir 	}
1051*cdf0e10cSrcweir 
1052*cdf0e10cSrcweir 	// ggf. Trennpunkte bei jedem Tausender einfuegen
1053*cdf0e10cSrcweir     if( nVorKomma > 3 )
1054*cdf0e10cSrcweir 	{
1055*cdf0e10cSrcweir         String aThoSep( rLoc.getNumThousandSep() );
1056*cdf0e10cSrcweir         if ( aThoSep.Len() > 0 )
1057*cdf0e10cSrcweir         {
1058*cdf0e10cSrcweir             sal_Unicode cTho( aThoSep.GetChar(0) );
1059*cdf0e10cSrcweir             sal_Int32 i(nVorKomma - 3);
1060*cdf0e10cSrcweir 
1061*cdf0e10cSrcweir             while(i > 0)
1062*cdf0e10cSrcweir             {
1063*cdf0e10cSrcweir                 rStr.Insert(cTho, (xub_StrLen)i);
1064*cdf0e10cSrcweir                 i -= 3;
1065*cdf0e10cSrcweir             }
1066*cdf0e10cSrcweir         }
1067*cdf0e10cSrcweir 	}
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir 	if(!aStr.Len())
1070*cdf0e10cSrcweir 		aStr += aNullCode;
1071*cdf0e10cSrcweir 
1072*cdf0e10cSrcweir 	if(bNeg && (aStr.Len() > 1 || aStr.GetChar(0) != aNullCode))
1073*cdf0e10cSrcweir 	{
1074*cdf0e10cSrcweir 		rStr.Insert(sal_Unicode('-'), 0);
1075*cdf0e10cSrcweir 	}
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir 	rStr = aStr;
1078*cdf0e10cSrcweir }
1079*cdf0e10cSrcweir 
1080*cdf0e10cSrcweir void SdrFormatter::TakeUnitStr(MapUnit eUnit, XubString& rStr)
1081*cdf0e10cSrcweir {
1082*cdf0e10cSrcweir 	switch(eUnit)
1083*cdf0e10cSrcweir 	{
1084*cdf0e10cSrcweir 		// Metrisch
1085*cdf0e10cSrcweir 		case MAP_100TH_MM   :
1086*cdf0e10cSrcweir 		{
1087*cdf0e10cSrcweir 			sal_Char aText[] = "/100mm";
1088*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1089*cdf0e10cSrcweir 			break;
1090*cdf0e10cSrcweir 		}
1091*cdf0e10cSrcweir 		case MAP_10TH_MM    :
1092*cdf0e10cSrcweir 		{
1093*cdf0e10cSrcweir 			sal_Char aText[] = "/10mm";
1094*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1095*cdf0e10cSrcweir 			break;
1096*cdf0e10cSrcweir 		}
1097*cdf0e10cSrcweir 		case MAP_MM         :
1098*cdf0e10cSrcweir 		{
1099*cdf0e10cSrcweir 			sal_Char aText[] = "mm";
1100*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1101*cdf0e10cSrcweir 			break;
1102*cdf0e10cSrcweir 		}
1103*cdf0e10cSrcweir 		case MAP_CM         :
1104*cdf0e10cSrcweir 		{
1105*cdf0e10cSrcweir 			sal_Char aText[] = "cm";
1106*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1107*cdf0e10cSrcweir 			break;
1108*cdf0e10cSrcweir 		}
1109*cdf0e10cSrcweir 
1110*cdf0e10cSrcweir 		// Inch
1111*cdf0e10cSrcweir 		case MAP_1000TH_INCH:
1112*cdf0e10cSrcweir 		{
1113*cdf0e10cSrcweir 			sal_Char aText[] = "/1000\"";
1114*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1115*cdf0e10cSrcweir 			break;
1116*cdf0e10cSrcweir 		}
1117*cdf0e10cSrcweir 		case MAP_100TH_INCH :
1118*cdf0e10cSrcweir 		{
1119*cdf0e10cSrcweir 			sal_Char aText[] = "/100\"";
1120*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1121*cdf0e10cSrcweir 			break;
1122*cdf0e10cSrcweir 		}
1123*cdf0e10cSrcweir 		case MAP_10TH_INCH  :
1124*cdf0e10cSrcweir 		{
1125*cdf0e10cSrcweir 			sal_Char aText[] = "/10\"";
1126*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1127*cdf0e10cSrcweir 			break;
1128*cdf0e10cSrcweir 		}
1129*cdf0e10cSrcweir 		case MAP_INCH       :
1130*cdf0e10cSrcweir 		{
1131*cdf0e10cSrcweir 			rStr = UniString();
1132*cdf0e10cSrcweir 			rStr += sal_Unicode('"');
1133*cdf0e10cSrcweir 			break;
1134*cdf0e10cSrcweir 		}
1135*cdf0e10cSrcweir 		case MAP_POINT      :
1136*cdf0e10cSrcweir 		{
1137*cdf0e10cSrcweir 			sal_Char aText[] = "pt";
1138*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1139*cdf0e10cSrcweir 			break;
1140*cdf0e10cSrcweir 		}
1141*cdf0e10cSrcweir 		case MAP_TWIP       :
1142*cdf0e10cSrcweir 		{
1143*cdf0e10cSrcweir 			sal_Char aText[] = "twip";
1144*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1145*cdf0e10cSrcweir 			break;
1146*cdf0e10cSrcweir 		}
1147*cdf0e10cSrcweir 
1148*cdf0e10cSrcweir 		// Sonstiges
1149*cdf0e10cSrcweir 		case MAP_PIXEL      :
1150*cdf0e10cSrcweir 		{
1151*cdf0e10cSrcweir 			sal_Char aText[] = "pixel";
1152*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1153*cdf0e10cSrcweir 			break;
1154*cdf0e10cSrcweir 		}
1155*cdf0e10cSrcweir 		case MAP_SYSFONT    :
1156*cdf0e10cSrcweir 		{
1157*cdf0e10cSrcweir 			sal_Char aText[] = "sysfont";
1158*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1159*cdf0e10cSrcweir 			break;
1160*cdf0e10cSrcweir 		}
1161*cdf0e10cSrcweir 		case MAP_APPFONT    :
1162*cdf0e10cSrcweir 		{
1163*cdf0e10cSrcweir 			sal_Char aText[] = "appfont";
1164*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1165*cdf0e10cSrcweir 			break;
1166*cdf0e10cSrcweir 		}
1167*cdf0e10cSrcweir 		case MAP_RELATIVE   :
1168*cdf0e10cSrcweir 		{
1169*cdf0e10cSrcweir 			rStr = UniString();
1170*cdf0e10cSrcweir 			rStr += sal_Unicode('%');
1171*cdf0e10cSrcweir 			break;
1172*cdf0e10cSrcweir 		}
1173*cdf0e10cSrcweir 		default: break;
1174*cdf0e10cSrcweir 	}
1175*cdf0e10cSrcweir }
1176*cdf0e10cSrcweir 
1177*cdf0e10cSrcweir void SdrFormatter::TakeUnitStr(FieldUnit eUnit, XubString& rStr)
1178*cdf0e10cSrcweir {
1179*cdf0e10cSrcweir 	switch(eUnit)
1180*cdf0e10cSrcweir 	{
1181*cdf0e10cSrcweir 		default				:
1182*cdf0e10cSrcweir 		case FUNIT_NONE		:
1183*cdf0e10cSrcweir 		case FUNIT_CUSTOM	:
1184*cdf0e10cSrcweir 		{
1185*cdf0e10cSrcweir 			rStr = UniString();
1186*cdf0e10cSrcweir 			break;
1187*cdf0e10cSrcweir 		}
1188*cdf0e10cSrcweir 
1189*cdf0e10cSrcweir 		// Metrisch
1190*cdf0e10cSrcweir 		case FUNIT_100TH_MM:
1191*cdf0e10cSrcweir 		{
1192*cdf0e10cSrcweir 			sal_Char aText[] = "/100mm";
1193*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1194*cdf0e10cSrcweir 			break;
1195*cdf0e10cSrcweir 		}
1196*cdf0e10cSrcweir 		case FUNIT_MM     :
1197*cdf0e10cSrcweir 		{
1198*cdf0e10cSrcweir 			sal_Char aText[] = "mm";
1199*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1200*cdf0e10cSrcweir 			break;
1201*cdf0e10cSrcweir 		}
1202*cdf0e10cSrcweir 		case FUNIT_CM     :
1203*cdf0e10cSrcweir 		{
1204*cdf0e10cSrcweir 			sal_Char aText[] = "cm";
1205*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1206*cdf0e10cSrcweir 			break;
1207*cdf0e10cSrcweir 		}
1208*cdf0e10cSrcweir 		case FUNIT_M      :
1209*cdf0e10cSrcweir 		{
1210*cdf0e10cSrcweir 			rStr = UniString();
1211*cdf0e10cSrcweir 			rStr += sal_Unicode('m');
1212*cdf0e10cSrcweir 			break;
1213*cdf0e10cSrcweir 		}
1214*cdf0e10cSrcweir 		case FUNIT_KM     :
1215*cdf0e10cSrcweir 		{
1216*cdf0e10cSrcweir 			sal_Char aText[] = "km";
1217*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1218*cdf0e10cSrcweir 			break;
1219*cdf0e10cSrcweir 		}
1220*cdf0e10cSrcweir 
1221*cdf0e10cSrcweir 		// Inch
1222*cdf0e10cSrcweir 		case FUNIT_TWIP   :
1223*cdf0e10cSrcweir 		{
1224*cdf0e10cSrcweir 			sal_Char aText[] = "twip";
1225*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1226*cdf0e10cSrcweir 			break;
1227*cdf0e10cSrcweir 		}
1228*cdf0e10cSrcweir 		case FUNIT_POINT  :
1229*cdf0e10cSrcweir 		{
1230*cdf0e10cSrcweir 			sal_Char aText[] = "pt";
1231*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1232*cdf0e10cSrcweir 			break;
1233*cdf0e10cSrcweir 		}
1234*cdf0e10cSrcweir 		case FUNIT_PICA   :
1235*cdf0e10cSrcweir 		{
1236*cdf0e10cSrcweir 			sal_Char aText[] = "pica";
1237*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1238*cdf0e10cSrcweir 			break;
1239*cdf0e10cSrcweir 		}
1240*cdf0e10cSrcweir 		case FUNIT_INCH   :
1241*cdf0e10cSrcweir 		{
1242*cdf0e10cSrcweir 			rStr = UniString();
1243*cdf0e10cSrcweir 			rStr += sal_Unicode('"');
1244*cdf0e10cSrcweir 			break;
1245*cdf0e10cSrcweir 		}
1246*cdf0e10cSrcweir 		case FUNIT_FOOT   :
1247*cdf0e10cSrcweir 		{
1248*cdf0e10cSrcweir 			sal_Char aText[] = "ft";
1249*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1250*cdf0e10cSrcweir 			break;
1251*cdf0e10cSrcweir 		}
1252*cdf0e10cSrcweir 		case FUNIT_MILE   :
1253*cdf0e10cSrcweir 		{
1254*cdf0e10cSrcweir 			sal_Char aText[] = "mile(s)";
1255*cdf0e10cSrcweir 			rStr = UniString(aText, sizeof(aText-1));
1256*cdf0e10cSrcweir 			break;
1257*cdf0e10cSrcweir 		}
1258*cdf0e10cSrcweir 
1259*cdf0e10cSrcweir 		// sonstiges
1260*cdf0e10cSrcweir 		case FUNIT_PERCENT:
1261*cdf0e10cSrcweir 		{
1262*cdf0e10cSrcweir 			rStr = UniString();
1263*cdf0e10cSrcweir 			rStr += sal_Unicode('%');
1264*cdf0e10cSrcweir 			break;
1265*cdf0e10cSrcweir 		}
1266*cdf0e10cSrcweir 	}
1267*cdf0e10cSrcweir }
1268*cdf0e10cSrcweir 
1269*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1270*cdf0e10cSrcweir 
1271*cdf0e10cSrcweir 
1272