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