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