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